OrcaSlicer/src/slic3r/GUI/CalibrationWizard.cpp
liz.li e2934516ed NEW: support restore calibration status of printer
1.store each printer's calibration status to appconfig.
2.add retraction calibration
3.add choose fine calibration directly at flowrate calibration
4.add start pages for every calibration
5.add history window for pa calibration

Change-Id: I117fd46e689e0573e70e8579f5a52ba62d99f3d6
2023-07-07 17:29:08 +08:00

3510 lines
No EOL
141 KiB
C++

#include "CalibrationWizard.hpp"
#include "I18N.hpp"
#include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include "../../libslic3r/Calib.hpp"
#include "Tabbook.hpp"
namespace Slic3r { namespace GUI {
#define CALIBRATION_DEBUG
#define PRESET_GAP FromDIP(25)
#define CALIBRATION_COMBOX_SIZE wxSize(FromDIP(500), FromDIP(24))
#define CALIBRATION_FILAMENT_COMBOX_SIZE wxSize(FromDIP(250), FromDIP(24))
#define CALIBRATION_OPTIMAL_INPUT_SIZE wxSize(FromDIP(300), FromDIP(24))
#define CALIBRATION_FROM_TO_INPUT_SIZE wxSize(FromDIP(160), FromDIP(24))
#define CALIBRATION_FGSIZER_HGAP FromDIP(50)
#define CALIBRATION_TEXT_MAX_LENGTH FromDIP(90) + CALIBRATION_FGSIZER_HGAP + 2 * CALIBRATION_FILAMENT_COMBOX_SIZE.x
#define CALIBRATION_PROGRESSBAR_LENGTH FromDIP(600)
static const wxString NA_STR = _L("N/A");
wxDEFINE_EVENT(EVT_CALIBRATION_TRAY_SELECTION_CHANGED, SimpleEvent);
wxDEFINE_EVENT(EVT_CALIBRATION_NOTIFY_CHANGE_PAGES, SimpleEvent);
wxDEFINE_EVENT(EVT_CALIBRATION_TAB_CHANGED, wxCommandEvent);
static bool is_high_end_type(MachineObject* obj) {
if (obj) {
if (obj->printer_type == "BL-P001" || obj->printer_type == "BL-P002")
return true;
else if (obj->printer_type == "C11" || obj->printer_type == "C12")
return false;
}
return false;
}
FilamentComboBox::FilamentComboBox(wxWindow* parent, const wxPoint& pos, const wxSize& size)
: wxPanel(parent, wxID_ANY, pos, size, wxTAB_TRAVERSAL)
{
wxBoxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
m_comboBox = new CalibrateFilamentComboBox(this);
m_comboBox->SetSize(CALIBRATION_FILAMENT_COMBOX_SIZE);
m_comboBox->SetMinSize(CALIBRATION_FILAMENT_COMBOX_SIZE);
main_sizer->Add(m_comboBox->clr_picker, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(8));
main_sizer->Add(m_comboBox, 0, wxALIGN_CENTER);
this->SetSizer(main_sizer);
this->Layout();
main_sizer->Fit(this);
}
void FilamentComboBox::set_select_mode(FilamentSelectMode mode)
{
m_mode = mode;
if (m_checkBox)
m_checkBox->Show(m_mode == FSMCheckBoxMode);
if (m_radioBox)
m_radioBox->Show(m_mode == FSMRadioMode);
Layout();
}
void FilamentComboBox::load_tray_from_ams(int id, DynamicPrintConfig& tray)
{
m_comboBox->load_tray(tray);
m_tray_id = id;
m_tray_name = m_comboBox->get_tray_name();
m_is_bbl_filamnet = MachineObject::is_bbl_filament(m_comboBox->get_tag_uid());
Enable(m_comboBox->is_tray_exist());
if (m_comboBox->is_tray_exist()) {
if (!m_comboBox->is_compatible_with_printer())
SetValue(false);
if (m_radioBox)
m_radioBox->Enable(m_comboBox->is_compatible_with_printer());
if (m_checkBox)
m_checkBox->Enable(m_comboBox->is_compatible_with_printer());
}
}
void FilamentComboBox::update_from_preset() { m_comboBox->update(); }
bool FilamentComboBox::Show(bool show)
{
bool result = true;
if (m_radioBox && m_mode == FSMRadioMode)
result = result && m_radioBox->Show(show);
if (m_checkBox && m_mode == FSMCheckBoxMode)
result = result && m_checkBox->Show(show);
result = result && wxPanel::Show(show);
return result;
}
bool FilamentComboBox::Enable(bool enable) {
if (!enable)
SetValue(false);
bool result = true;
if (m_radioBox)
result = result && m_radioBox->Enable(enable);
if (m_checkBox)
result = result && m_checkBox->Enable(enable);
result = result && wxPanel::Enable(enable);
return result;
}
void FilamentComboBox::SetValue(bool value) {
if (m_radioBox)
m_radioBox->SetValue(value);
if (m_checkBox)
m_checkBox->SetValue(value);
SimpleEvent e(EVT_CALIBRATION_TRAY_SELECTION_CHANGED);
e.ResumePropagation(wxEVENT_PROPAGATE_MAX);
e.SetEventObject(this);
GetEventHandler()->ProcessEvent(e);
}
CalibrationWizard::CalibrationWizard(wxWindow* parent, CalibMode mode, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: wxPanel(parent, id, pos, size, style)
, m_mode(mode)
{
SetBackgroundColour(wxColour(0xEEEEEE));
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 5);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_all_pages_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow->SetSizer(m_all_pages_sizer);
m_scrolledWindow->Layout();
m_all_pages_sizer->Fit(m_scrolledWindow);
main_sizer->Add(m_scrolledWindow, 1, wxEXPAND | wxALL, FromDIP(10));
this->SetSizer(main_sizer);
this->Layout();
main_sizer->Fit(this);
init_bitmaps();
init_printer_calib_info_from_appconfig();
Bind(EVT_CALIBRATIONPAGE_PREV, &CalibrationWizard::on_click_btn_prev, this);
Bind(EVT_CALIBRATIONPAGE_NEXT, &CalibrationWizard::on_click_btn_next, this);
Bind(EVT_CALIBRATION_TRAY_SELECTION_CHANGED, &CalibrationWizard::on_select_tray, this);
#ifdef CALIBRATION_DEBUG
this->Bind(wxEVT_CHAR_HOOK, [this](auto& evt) {
const int keyCode = evt.GetKeyCode();
switch (keyCode)
{
case WXK_NUMPAD_PAGEUP: case WXK_PAGEUP:
show_page(get_curr_page()->get_prev_page());
break;
case WXK_NUMPAD_PAGEDOWN: case WXK_PAGEDOWN:
{
show_page(get_curr_page()->get_next_page());
break;
}
default:
evt.Skip();
break;
}
});
#endif
}
CalibrationWizardPage* CalibrationWizard::create_presets_page(bool need_custom_range) {
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Preset);
page->set_highlight_step_text(PageType::Preset);
auto page_content_sizer = page->get_content_vsizer();
m_presets_panel = new wxPanel(page);
page_content_sizer->Add(m_presets_panel, 0, wxEXPAND, 0);
auto panel_sizer = new wxBoxSizer(wxVERTICAL);
m_presets_panel->SetSizer(panel_sizer);
auto nozzle_combo_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("Nozzle"), wxDefaultPosition, wxDefaultSize, 0);
nozzle_combo_text->Wrap(-1);
nozzle_combo_text->SetFont(Label::Head_14);
panel_sizer->Add(nozzle_combo_text, 0, wxALL, 0);
m_comboBox_nozzle_dia = new ComboBox(m_presets_panel, wxID_ANY, "", wxDefaultPosition, CALIBRATION_COMBOX_SIZE, 0, nullptr, wxCB_READONLY);
panel_sizer->Add(m_comboBox_nozzle_dia, 0, wxALL, 0);
panel_sizer->AddSpacer(PRESET_GAP);
auto plate_type_combo_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("Plate Type"), wxDefaultPosition, wxDefaultSize, 0);
plate_type_combo_text->Wrap(-1);
plate_type_combo_text->SetFont(Label::Head_14);
panel_sizer->Add(plate_type_combo_text, 0, wxALL, 0);
m_comboBox_bed_type = new ComboBox(m_presets_panel, wxID_ANY, "", wxDefaultPosition, CALIBRATION_COMBOX_SIZE, 0, nullptr, wxCB_READONLY);
panel_sizer->Add(m_comboBox_bed_type, 0, wxALL, 0);
panel_sizer->AddSpacer(PRESET_GAP);
{// Hide
auto process_combo_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("Process"), wxDefaultPosition, wxDefaultSize, 0);
process_combo_text->Hide();
process_combo_text->Wrap(-1);
panel_sizer->Add(process_combo_text, 0, wxALL, 0);
m_comboBox_process = new ComboBox(m_presets_panel, wxID_ANY, "", wxDefaultPosition, CALIBRATION_COMBOX_SIZE, 0, nullptr, wxCB_READONLY);
m_comboBox_process->Hide();
panel_sizer->Add(m_comboBox_process, 0, wxALL, 0);
}// Hide
m_select_ams_mode_panel = new wxPanel(m_presets_panel);
auto choose_ams_sizer = new wxBoxSizer(wxVERTICAL);
auto filament_from_text = new wxStaticText(m_select_ams_mode_panel, wxID_ANY, _L("Filament From"), wxDefaultPosition, wxDefaultSize, 0);
filament_from_text->SetFont(Label::Head_14);
choose_ams_sizer->Add(filament_from_text, 0);
auto raioBox_sizer = new wxFlexGridSizer(2, 1, 0, FromDIP(10));
m_ams_radiobox = new wxRadioButton(m_select_ams_mode_panel, wxID_ANY, _L("AMS"));
m_ams_radiobox->SetValue(true);
raioBox_sizer->Add(m_ams_radiobox, 0);
//auto ams_text = new wxStaticText(m_choose_ams_panel, wxID_ANY, _L("AMS"), wxDefaultPosition, wxDefaultSize, 0);
//raioBox_sizer->Add(ams_text);
m_ext_spool_radiobox = new wxRadioButton(m_select_ams_mode_panel, wxID_ANY, _L("External Spool"));
raioBox_sizer->Add(m_ext_spool_radiobox, 0);
//auto ext_spool_text = new wxStaticText(m_choose_ams_panel, wxID_ANY, _L("External Spool"), wxDefaultPosition, wxDefaultSize, 0);
//raioBox_sizer->Add(ext_spool_text, 0);
choose_ams_sizer->Add(raioBox_sizer, 0);
m_select_ams_mode_panel->SetSizer(choose_ams_sizer);
panel_sizer->Add(m_select_ams_mode_panel, 0);
panel_sizer->AddSpacer(PRESET_GAP);
auto filament_for_title_sizer = new wxBoxSizer(wxHORIZONTAL);
auto filament_for_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("Filament For Calibration"), wxDefaultPosition, wxDefaultSize, 0);
filament_for_text->SetFont(Label::Head_14);
filament_for_title_sizer->Add(filament_for_text, 0, wxALIGN_CENTER);
filament_for_title_sizer->AddSpacer(FromDIP(25));
m_ams_sync_button = new ScalableButton(m_presets_panel, wxID_ANY, "ams_fila_sync", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 18);
m_ams_sync_button->SetBackgroundColour(*wxWHITE);
m_ams_sync_button->SetToolTip(_L("Synchronize filament list from AMS"));
filament_for_title_sizer->Add(m_ams_sync_button, 0, wxALIGN_CENTER, 0);
panel_sizer->Add(filament_for_title_sizer);
m_filament_list_panel = new wxPanel(m_presets_panel);
auto filament_list_sizer = new wxBoxSizer(wxVERTICAL);
auto filament_list_tips = new wxStaticText(m_filament_list_panel, wxID_ANY, _L("Please select same type of material, because plate temperature might not be compatible with different type of material"), wxDefaultPosition, wxDefaultSize, 0);
filament_list_tips->SetFont(Label::Body_13);
filament_list_tips->SetForegroundColour(wxColour(145, 145, 145));
filament_list_tips->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
filament_list_sizer->Add(filament_list_tips);
filament_list_sizer->AddSpacer(FromDIP(10));
m_muilti_ams_panel = new wxPanel(m_filament_list_panel);
auto multi_ams_sizer = new wxBoxSizer(wxVERTICAL);
auto ams_items_sizer = new wxBoxSizer(wxHORIZONTAL);
for (int i = 0; i < 4; i++) {
AMSinfo temp_info = AMSinfo{ std::to_string(i), std::vector<Caninfo>{} };
auto amsitem = new AMSItem(m_muilti_ams_panel, wxID_ANY, temp_info);
amsitem->Bind(wxEVT_LEFT_DOWN, [this, amsitem](wxMouseEvent& e) {
on_switch_ams(amsitem->m_amsinfo.ams_id);
e.Skip();
});
m_ams_item_list.push_back(amsitem);
ams_items_sizer->Add(amsitem, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(6));
}
multi_ams_sizer->Add(ams_items_sizer, 0);
multi_ams_sizer->AddSpacer(FromDIP(10));
m_muilti_ams_panel->SetSizer(multi_ams_sizer);
filament_list_sizer->Add(m_muilti_ams_panel);
m_muilti_ams_panel->Hide();
auto filament_fgSizer = new wxFlexGridSizer(2, 2, FromDIP(10), CALIBRATION_FGSIZER_HGAP);
for (int i = 0; i < 16; i++) {
auto filament_comboBox_sizer = new wxBoxSizer(wxHORIZONTAL);
wxRadioButton* radio_btn = new wxRadioButton(m_filament_list_panel, wxID_ANY, "");
CheckBox* check_box = new CheckBox(m_filament_list_panel);
check_box->SetBackgroundColour(*wxWHITE);
FilamentComboBox* fcb = new FilamentComboBox(m_filament_list_panel);
fcb->SetRadioBox(radio_btn);
fcb->SetCheckBox(check_box);
fcb->set_select_mode(FilamentSelectMode::FSMRadioMode);
filament_comboBox_sizer->Add(radio_btn, 0, wxALIGN_CENTER);
filament_comboBox_sizer->Add(check_box, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(8));
filament_comboBox_sizer->Add(fcb, 0, wxALIGN_CENTER);
filament_fgSizer->Add(filament_comboBox_sizer, 0);
radio_btn->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent& event) {
SimpleEvent e(EVT_CALIBRATION_TRAY_SELECTION_CHANGED);
e.SetEventObject(this);
wxPostEvent(this, e);
event.Skip();
});
check_box->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& event) {
SimpleEvent e(EVT_CALIBRATION_TRAY_SELECTION_CHANGED);
e.SetEventObject(this);
wxPostEvent(this, e);
event.Skip();
});
m_filament_comboBox_list.push_back(fcb);
if (i >= 4)
fcb->Show(false);
}
filament_list_sizer->Add(filament_fgSizer, 0);
m_filament_list_panel->SetSizer(filament_list_sizer);
panel_sizer->Add(m_filament_list_panel, 0);
{// Hide
m_virtual_panel = new wxPanel(m_presets_panel);
auto virtual_sizer = new wxBoxSizer(wxHORIZONTAL);
virtual_sizer->AddSpacer(FromDIP(10));
wxRadioButton* radio_btn = new wxRadioButton(m_virtual_panel, wxID_ANY, "");
CheckBox* check_box = new CheckBox(m_virtual_panel);
m_virtual_tray_comboBox = new FilamentComboBox(m_virtual_panel);
m_virtual_tray_comboBox->SetRadioBox(radio_btn);
m_virtual_tray_comboBox->SetCheckBox(check_box);
m_virtual_tray_comboBox->set_select_mode(FilamentSelectMode::FSMRadioMode);
radio_btn->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent& event) {
SimpleEvent e(EVT_CALIBRATION_TRAY_SELECTION_CHANGED);
e.SetEventObject(this);
wxPostEvent(this, e);
event.Skip();
});
virtual_sizer->Add(radio_btn, 0, wxALIGN_CENTER);
virtual_sizer->Add(check_box, 0, wxALIGN_CENTER);
virtual_sizer->Add(m_virtual_tray_comboBox, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(8));
m_virtual_panel->SetSizer(virtual_sizer);
m_virtual_panel->Hide();
panel_sizer->Add(m_virtual_panel, 0);
}// Hide
m_filaments_incompatible_tips = new wxStaticText(m_presets_panel, wxID_ANY, _L(""));
m_filaments_incompatible_tips->SetFont(Label::Body_13);
m_filaments_incompatible_tips->SetForegroundColour(wxColour(230, 92, 92));
m_filaments_incompatible_tips->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
m_filaments_incompatible_tips->Hide();
panel_sizer->Add(m_filaments_incompatible_tips, 0, wxEXPAND);
m_bed_type_incompatible_tips = new wxStaticText(m_presets_panel, wxID_ANY, _L(""));
m_bed_type_incompatible_tips->SetFont(Label::Body_13);
m_bed_type_incompatible_tips->SetForegroundColour(wxColour(230, 92, 92));
m_bed_type_incompatible_tips->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
m_bed_type_incompatible_tips->Hide();
panel_sizer->Add(m_bed_type_incompatible_tips, 0, wxEXPAND);
panel_sizer->AddSpacer(PRESET_GAP);
if (need_custom_range) {
wxBoxSizer* horiz_sizer;
horiz_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* from_sizer;
from_sizer = new wxBoxSizer(wxVERTICAL);
m_from_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("From"), wxDefaultPosition, wxDefaultSize, 0);
m_from_text->Wrap(-1);
m_from_text->SetFont(::Label::Body_14);
from_sizer->Add(m_from_text, 0, wxALL, 0);
m_from_value = new TextInput(m_presets_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, 0);
m_from_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
from_sizer->Add(m_from_value, 0, wxALL, 0);
horiz_sizer->Add(from_sizer, 0, wxEXPAND, 0);
horiz_sizer->Add(FromDIP(10), 0, 0, wxEXPAND, 0);
wxBoxSizer* to_sizer;
to_sizer = new wxBoxSizer(wxVERTICAL);
m_to_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("To"), wxDefaultPosition, wxDefaultSize, 0);
m_to_text->Wrap(-1);
m_to_text->SetFont(::Label::Body_14);
to_sizer->Add(m_to_text, 0, wxALL, 0);
m_to_value = new TextInput(m_presets_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, 0);
m_to_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
to_sizer->Add(m_to_value, 0, wxALL, 0);
horiz_sizer->Add(to_sizer, 0, wxEXPAND, 0);
horiz_sizer->Add(FromDIP(10), 0, 0, wxEXPAND, 0);
wxBoxSizer* step_sizer;
step_sizer = new wxBoxSizer(wxVERTICAL);
m_step_text = new wxStaticText(m_presets_panel, wxID_ANY, _L("Step"), wxDefaultPosition, wxDefaultSize, 0);
m_step_text->Wrap(-1);
m_step_text->SetFont(::Label::Body_14);
step_sizer->Add(m_step_text, 0, wxALL, 0);
m_step = new TextInput(m_presets_panel, "5", _L("\u2103"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, 0);
m_step->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
step_sizer->Add(m_step, 0, wxALL, 0);
horiz_sizer->Add(step_sizer, 0, wxEXPAND, 0);
panel_sizer->Add(horiz_sizer, 0, wxEXPAND, 0);
panel_sizer->AddSpacer(PRESET_GAP);
}
else {
m_from_text = nullptr;
m_to_text = nullptr;
m_from_value = nullptr;
m_to_value = nullptr;
m_step_text = nullptr;
m_step = nullptr;
}
auto printing_param_panel = new wxPanel(m_presets_panel);
printing_param_panel->SetBackgroundColour(wxColour(217, 217, 217));
printing_param_panel->SetMinSize(wxSize(CALIBRATION_TEXT_MAX_LENGTH * 1.7f, -1));
auto printing_param_sizer = new wxBoxSizer(wxVERTICAL);
printing_param_panel->SetSizer(printing_param_sizer);
printing_param_sizer->AddSpacer(FromDIP(10));
auto preset_panel_tips = new wxStaticText(printing_param_panel, wxID_ANY, _L("A test model will be printed. Please clear the build plate and place it back to the hot bed before calibration."));
preset_panel_tips->SetFont(Label::Body_14);
preset_panel_tips->Wrap(CALIBRATION_TEXT_MAX_LENGTH * 1.5f);
printing_param_sizer->Add(preset_panel_tips, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
printing_param_sizer->AddSpacer(FromDIP(10));
auto printing_param_text = new wxStaticText(printing_param_panel, wxID_ANY, _L("Printing Parameters"));
printing_param_text->SetFont(Label::Head_12);
printing_param_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
printing_param_sizer->Add(printing_param_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
auto info_sizer = new wxFlexGridSizer(0, 3, 0, FromDIP(10));
info_sizer->SetFlexibleDirection(wxBOTH);
info_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
auto nozzle_temp_sizer = new wxBoxSizer(wxVERTICAL);
auto nozzle_temp_text = new wxStaticText(printing_param_panel, wxID_ANY, _L("Nozzle temperature"));
nozzle_temp_text->SetFont(Label::Body_12);
m_nozzle_temp = new TextInput(printing_param_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY);
m_nozzle_temp->SetBorderWidth(0);
nozzle_temp_sizer->Add(nozzle_temp_text, 0, wxALIGN_LEFT);
nozzle_temp_sizer->Add(m_nozzle_temp, 0, wxEXPAND);
auto bed_temp_sizer = new wxBoxSizer(wxVERTICAL);
auto bed_temp_text = new wxStaticText(printing_param_panel, wxID_ANY, _L("Bed temperature"));
bed_temp_text->SetFont(Label::Body_12);
m_bed_temp = new TextInput(printing_param_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY);
m_bed_temp->SetBorderWidth(0);
bed_temp_sizer->Add(bed_temp_text, 0, wxALIGN_LEFT);
bed_temp_sizer->Add(m_bed_temp, 0, wxEXPAND);
auto max_flow_sizer = new wxBoxSizer(wxVERTICAL);
auto max_flow_text = new wxStaticText(printing_param_panel, wxID_ANY, _L("Max volumetric speed"));
max_flow_text->SetFont(Label::Body_12);
m_max_volumetric_speed = new TextInput(printing_param_panel, wxEmptyString, _L("mm\u00B3"), "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY);
m_max_volumetric_speed->SetBorderWidth(0);
max_flow_sizer->Add(max_flow_text, 0, wxALIGN_LEFT);
max_flow_sizer->Add(m_max_volumetric_speed, 0, wxEXPAND);
m_nozzle_temp->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto&) {});
m_bed_temp->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto&) {});
m_max_volumetric_speed->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto&) {});
info_sizer->Add(nozzle_temp_sizer);
info_sizer->Add(bed_temp_sizer);
info_sizer->Add(max_flow_sizer);
printing_param_sizer->Add(info_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
printing_param_sizer->AddSpacer(FromDIP(10));
panel_sizer->Add(printing_param_panel, 0);
init_presets_selections();
auto page_btn_sizer = page->get_btn_hsizer();
auto page_prev_btn = page->get_prev_btn();
page_prev_btn->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Calibrate"));
page_next_btn->SetButtonType(ButtonType::Calibrate);
m_send_progress_panel = new wxPanel(page);
m_send_progress_panel->Hide();
auto send_panel_sizer = new wxBoxSizer(wxVERTICAL);
m_send_progress_panel->SetSizer(send_panel_sizer);
m_send_progress_bar = std::shared_ptr<BBLStatusBarSend>(new BBLStatusBarSend(m_send_progress_panel));
m_send_progress_bar->set_cancel_callback_fina([this]() {
BOOST_LOG_TRIVIAL(info) << "CalibrationWizard::print_job: enter canceled";
if (CalibUtils::print_job) {
if (CalibUtils::print_job->is_running()) {
BOOST_LOG_TRIVIAL(info) << "calibration_print_job: canceled";
CalibUtils::print_job->cancel();
}
CalibUtils::print_job->join();
}
show_send_progress_bar(false);
});
send_panel_sizer->Add(m_send_progress_bar->get_panel(), 0, wxALIGN_CENTER, 0);
page_btn_sizer->Insert(1, m_send_progress_panel, 0, wxALIGN_CENTER, 0);
m_presets_panel->Layout();
panel_sizer->Fit(m_presets_panel);
m_comboBox_nozzle_dia->Bind(wxEVT_COMBOBOX, &CalibrationWizard::on_select_nozzle, this);
Bind(EVT_CALIBRATION_TAB_CHANGED, &CalibrationWizard::on_select_nozzle, this);
m_comboBox_bed_type->Bind(wxEVT_COMBOBOX, &CalibrationWizard::on_select_bed_type, this);
m_ams_sync_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
on_update_ams_filament();
});
m_ams_radiobox->Bind(wxEVT_RADIOBUTTON, &CalibrationWizard::on_choose_ams, this);
m_ext_spool_radiobox->Bind(wxEVT_RADIOBUTTON, &CalibrationWizard::on_choose_ext_spool, this);
return page;
}
CalibrationWizardPage* CalibrationWizard::create_print_page() {
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Calibration);
page->set_highlight_step_text(PageType::Calibration);
auto sizer = page->get_content_vsizer();
m_print_picture = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
sizer->Add(m_print_picture, 0, wxALIGN_CENTER, 0);
sizer->AddSpacer(FromDIP(20));
m_print_panel = new wxPanel(page);
m_print_panel->SetSize({ CALIBRATION_PROGRESSBAR_LENGTH, -1 });
m_print_panel->SetMinSize({ CALIBRATION_PROGRESSBAR_LENGTH, -1 });
page->get_prev_btn()->Hide();
m_btn_next = page->get_next_btn();
m_btn_next->SetLabel(_L("Next"));
m_btn_next->SetButtonType(ButtonType::Next);
sizer->Add(m_print_panel, 0, wxALIGN_CENTER, 0);
auto panel_sizer = new wxBoxSizer(wxVERTICAL);
m_staticText_profile_value = new wxStaticText(m_print_panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
m_staticText_profile_value->Wrap(-1);
m_staticText_profile_value->SetFont(Label::Body_14);
m_staticText_profile_value->SetForegroundColour(0x6B6B6B);
m_printing_stage_value = new wxStaticText(m_print_panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END);
m_printing_stage_value->SetFont(Label::Body_14);
m_printing_stage_value->Wrap(-1);
m_printing_stage_value->SetForegroundColour(wxColour(0, 174, 66));
wxPanel* panel_text = new wxPanel(m_print_panel);
panel_text->SetBackgroundColour(*wxWHITE);
wxBoxSizer* text_sizer = new wxBoxSizer(wxHORIZONTAL);
m_staticText_progress_percent = new wxStaticText(panel_text, wxID_ANY, "0%", wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_percent->SetFont(::Label::Head_18);
m_staticText_progress_percent->SetForegroundColour(wxColour(0, 174, 66));
m_staticText_layers = new wxStaticText(panel_text, wxID_ANY, _L("Layer: N/A"));
m_staticText_layers->SetFont(::Label::Body_15);
m_staticText_layers->SetForegroundColour(wxColour(146, 146, 146));
m_staticText_progress_left_time = new wxStaticText(panel_text, wxID_ANY, NA_STR, wxDefaultPosition, wxDefaultSize, 0);
m_staticText_progress_left_time->Wrap(-1);
m_staticText_progress_left_time->SetFont(::Label::Body_15);
m_staticText_progress_left_time->SetForegroundColour(wxColour(146, 146, 146));
text_sizer->Add(m_staticText_progress_percent, 0, wxALIGN_CENTER, 0);
text_sizer->Add(0, 0, 1, wxEXPAND, 0);
text_sizer->Add(m_staticText_layers, 0, wxALIGN_CENTER | wxALL, 0);
text_sizer->Add(0, 0, 0, wxLEFT, FromDIP(20));
text_sizer->Add(m_staticText_progress_left_time, 0, wxALIGN_CENTER | wxALL, 0);
text_sizer->AddSpacer(FromDIP(90));
panel_text->SetSizer(text_sizer);
auto panel_progressbar = new wxPanel(m_print_panel, wxID_ANY);
panel_progressbar->SetBackgroundColour(*wxWHITE);
auto progressbar_sizer = new wxBoxSizer(wxHORIZONTAL);
m_print_gauge_progress = new ProgressBar(panel_progressbar, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize);
m_print_gauge_progress->SetValue(0);
m_print_gauge_progress->SetHeight(FromDIP(8));
m_print_gauge_progress->SetSize(wxSize(FromDIP(400), -1));
m_print_gauge_progress->SetMinSize(wxSize(FromDIP(400), -1));
m_button_pause_resume = new ScalableButton(panel_progressbar, wxID_ANY, "print_control_pause", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_button_abort = new ScalableButton(panel_progressbar, wxID_ANY, "print_control_stop", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true);
m_button_abort->SetToolTip(_L("Stop"));
progressbar_sizer->Add(m_print_gauge_progress, 1, wxALIGN_CENTER_VERTICAL, 0);
progressbar_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progressbar_sizer->Add(m_button_pause_resume, 0, wxALL, FromDIP(5));
progressbar_sizer->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(18));
progressbar_sizer->Add(m_button_abort, 0, wxALL, FromDIP(5));
panel_progressbar->SetSizer(progressbar_sizer);
panel_sizer->AddSpacer(FromDIP(15));
panel_sizer->Add(m_staticText_profile_value, 0, wxEXPAND | wxTOP, FromDIP(5));
panel_sizer->Add(m_printing_stage_value, 0, wxEXPAND | wxTOP, FromDIP(5));
panel_sizer->Add(panel_text, 0, wxEXPAND, 0);
panel_sizer->Add(panel_progressbar, 0, wxEXPAND, 0);
panel_sizer->AddSpacer(FromDIP(15));
m_print_panel->SetSizer(panel_sizer);
m_print_panel->SetSizer(panel_sizer);
m_print_panel->Layout();
panel_sizer->Fit(m_print_panel);
m_button_pause_resume->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {
if (m_button_pause_resume->GetToolTipText() == _L("Pause")) {
m_button_pause_resume->SetBitmap(m_bitmap_pause_hover.bmp());
}
if (m_button_pause_resume->GetToolTipText() == _L("Resume")) {
m_button_pause_resume->SetBitmap(m_bitmap_resume_hover.bmp());
}
});
m_button_pause_resume->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {
if (m_button_pause_resume->GetToolTipText() == _L("Pause")) {
m_button_pause_resume->SetBitmap(m_bitmap_pause.bmp());
}
if (m_button_pause_resume->GetToolTipText() == _L("Resume")) {
m_button_pause_resume->SetBitmap(m_bitmap_resume.bmp());
}
});
m_button_pause_resume->Bind(wxEVT_BUTTON, &CalibrationWizard::on_subtask_pause_resume, this);
m_button_abort->Bind(wxEVT_ENTER_WINDOW, [this](auto& e) {
m_button_abort->SetBitmap(m_bitmap_abort_hover.bmp());
});
m_button_abort->Bind(wxEVT_LEAVE_WINDOW, [this](auto& e) {
m_button_abort->SetBitmap(m_bitmap_abort.bmp()); }
);
m_button_abort->Bind(wxEVT_BUTTON, &CalibrationWizard::on_subtask_abort, this);
return page;
}
CalibrationWizardPage* CalibrationWizard::create_save_page() {
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Save);
page->set_highlight_step_text(PageType::Save);
auto sizer = page->get_content_vsizer();
m_save_panel = new wxPanel(page);
sizer->Add(m_save_panel, 0, wxALIGN_CENTER, 0);
auto panel_sizer = new wxBoxSizer(wxVERTICAL);
m_save_panel->SetSizer(panel_sizer);
create_save_panel_content(panel_sizer);
auto page_prev_btn = page->get_prev_btn();
page_prev_btn->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Save"));
page_next_btn->SetButtonType(ButtonType::Save);
return page;
}
void CalibrationWizard::show_send_progress_bar(bool show)
{
m_send_progress_panel->Show(show);
if (get_curr_page()->get_next_btn()->GetButtonType() == Calibrate)
get_curr_page()->get_next_btn()->Show(!show);
Layout();
}
void CalibrationWizard::on_choose_ams(wxCommandEvent& event) {
m_filament_list_panel->Show();
m_virtual_panel->Hide();
m_filament_from_ext_spool = false;
m_virtual_tray_comboBox->SetValue(false);
Layout();
Refresh();
}
void CalibrationWizard::on_choose_ext_spool(wxCommandEvent& event) {
m_virtual_panel->Show();
m_filament_list_panel->Hide();
m_filament_from_ext_spool = true;
for (int i = 0; i < m_filament_comboBox_list.size(); i++) {
m_filament_comboBox_list[i]->SetValue(false);
}
Layout();
Refresh();
}
void CalibrationWizard::show_page(CalibrationWizardPage* page) {
if (!page)
return;
auto page_node = m_first_page;
while (page_node)
{
page_node->Hide();
page_node = page_node->get_next_page();
}
m_curr_page = page;
m_curr_page->Show();
Layout();
}
void CalibrationWizard::on_click_btn_prev(IntEvent& event)
{
ButtonType button_type = static_cast<ButtonType>(event.get_data());
switch (button_type)
{
case Slic3r::GUI::Back:
show_page(get_curr_page()->get_prev_page());
break;
case Slic3r::GUI::Recalibrate:
if (!curr_obj ||
curr_obj->is_system_printing() ||
curr_obj->is_in_printing()) {
MessageDialog msg_dlg(nullptr, _L("Is in printing. Please wait for printing to complete"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
show_page(get_frist_page());
break;
}
}
void CalibrationWizard::on_click_btn_next(IntEvent& event)
{
ButtonType button_type = static_cast<ButtonType>(event.get_data());
switch (button_type)
{
case Slic3r::GUI::Start:
show_page(get_curr_page()->get_next_page());
break;
case Slic3r::GUI::Next:
show_page(get_curr_page()->get_next_page());
save_to_printer_calib_info(m_curr_page->get_page_type());
break;
case Slic3r::GUI::Calibrate: {
if(!curr_obj){
MessageDialog msg_dlg(nullptr, _L("No Printer Connected!"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
if (curr_obj->is_connecting() || !curr_obj->is_connected()) {
MessageDialog msg_dlg(nullptr, _L("Printer is not connected yet."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
if (!m_printer_preset || !m_filament_preset || !m_print_preset) {
wxString tips;
if (!m_printer_preset) {
tips = _L("Please select a printer and nozzle for calibration.");
}
else if (!m_print_preset) {
tips = _L("No print preset");
}
else {
tips = _L("Please select filament for calibration.");
}
MessageDialog msg_dlg(nullptr, tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
if (curr_obj->is_system_printing() ||
curr_obj->is_in_printing()) {
MessageDialog msg_dlg(nullptr, _L("Is in printing. Please wait for printing to complete"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
std::vector<int> tray_ids = get_selected_tray();
if (start_calibration(tray_ids)) {
if (m_mode != CalibMode::Calib_Flow_Rate) {
save_to_printer_calib_info(PageType::Calibration);
}
}
break;
}
case Slic3r::GUI::Save:
if (!curr_obj ||
curr_obj->is_system_printing() ||
curr_obj->is_in_printing()) {
MessageDialog msg_dlg(nullptr, _L("Is in printing. Please wait for printing to complete"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
if (save_calibration_result()) {
save_to_printer_calib_info(PageType::Finish);
}
break;
default:
break;
}
}
void CalibrationWizard::init_printer_calib_info_from_appconfig() {
std::vector<PrinterCaliInfo> infos = wxGetApp().app_config->get_printer_cali_infos();
for (int i = 0; i < infos.size(); i++) {
if (m_printer_calib_infos.find(infos[i].dev_id) == m_printer_calib_infos.end()) {
m_printer_calib_infos[infos[i].dev_id].dev_id = infos[i].dev_id;
m_printer_calib_infos[infos[i].dev_id].filament_preset = infos[i].filament_preset;
m_printer_calib_infos[infos[i].dev_id].mode = infos[i].mode;
m_printer_calib_infos[infos[i].dev_id].state = infos[i].state;
}
}
}
void CalibrationWizard::save_to_printer_calib_info(PageType page_type) {
m_printer_calib_infos[curr_obj->dev_id].dev_id = curr_obj->dev_id;
m_printer_calib_infos[curr_obj->dev_id].mode = m_mode;
m_printer_calib_infos[curr_obj->dev_id].state = static_cast<Slic3r::CalibState>(page_type);
m_printer_calib_infos[curr_obj->dev_id].filament_preset = m_filament_preset->name;
wxGetApp().app_config->save_printer_cali_infos(m_printer_calib_infos[curr_obj->dev_id]);
}
void CalibrationWizard::update_print_progress()
{
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
// may change printer selection on Device
if (!dev || !curr_obj) {
reset_printing_values();
return;
}
// check valid machine
if (dev->get_my_machine(curr_obj->dev_id) == nullptr) {
reset_printing_values();
return;
}
if (curr_obj->is_connecting()) {
reset_printing_values();
return;
}
else if (!curr_obj->is_connected()) {
reset_printing_values();
return;
}
m_print_panel->Freeze();
if (curr_obj->is_support_layer_num) {
m_staticText_layers->Show();
}
else {
m_staticText_layers->Hide();
}
if (curr_obj->is_system_printing()) {
reset_printing_values();
}
else if (curr_obj->is_in_printing() || curr_obj->print_status == "FINISH") {
if (curr_obj->is_in_prepare() || curr_obj->print_status == "SLICING") {
reset_printing_values();
wxString prepare_text;
if (curr_obj->is_in_prepare())
prepare_text = wxString::Format(_L("Downloading..."));
else if (curr_obj->print_status == "SLICING") {
if (curr_obj->queue_number <= 0) {
prepare_text = wxString::Format(_L("Cloud Slicing..."));
}
else {
prepare_text = wxString::Format(_L("In Cloud Slicing Queue, there are %s tasks ahead."), std::to_string(curr_obj->queue_number));
}
}
else
prepare_text = wxString::Format(_L("Downloading..."));
if (curr_obj->gcode_file_prepare_percent >= 0 && curr_obj->gcode_file_prepare_percent <= 100)
prepare_text += wxString::Format("(%d%%)", curr_obj->gcode_file_prepare_percent);
m_printing_stage_value->SetLabelText(prepare_text);
wxString subtask_text = wxString::Format("%s", GUI::from_u8(curr_obj->subtask_name));
if (curr_obj->get_modeltask() && curr_obj->get_modeltask()->design_id > 0) {
if (!m_staticText_profile_value->IsShown()) { m_staticText_profile_value->Show(); }
m_staticText_profile_value->SetLabelText(wxString::FromUTF8(curr_obj->get_modeltask()->profile_name));
}
else {
m_staticText_profile_value->SetLabelText(wxEmptyString);
m_staticText_profile_value->Hide();
}
}
else {
if (curr_obj->can_resume()) {
m_button_pause_resume->SetBitmap(m_bitmap_resume.bmp());
if (m_button_pause_resume->GetToolTipText() != _L("Resume")) { m_button_pause_resume->SetToolTip(_L("Resume")); }
}
else {
m_button_pause_resume->SetBitmap(m_bitmap_pause.bmp());
if (m_button_pause_resume->GetToolTipText() != _L("Pause")) { m_button_pause_resume->SetToolTip(_L("Pause")); }
}
if (curr_obj->print_status == "FINISH") {// curr_obj->is_extrusion_cali_finished() also can get in
m_button_abort->Enable(false);
m_button_abort->SetBitmap(m_bitmap_abort_disable.bmp());
m_button_pause_resume->Enable(false);
m_button_pause_resume->SetBitmap(m_bitmap_resume_disable.bmp());
m_btn_next->Enable(true);
}
else {
m_button_abort->Enable(true);
m_button_abort->SetBitmap(m_bitmap_abort.bmp());
m_button_pause_resume->Enable(true);
m_btn_next->Enable(false);
}
// update printing stage
m_printing_stage_value->SetLabelText(curr_obj->get_curr_stage());
// update left time
std::string left_time;
try {
left_time = get_bbl_monitor_time_dhm(curr_obj->mc_left_time);
}
catch (...) {
;
}
wxString left_time_text = left_time.empty() ? NA_STR : wxString::Format("-%s", left_time);
m_staticText_progress_left_time->SetLabelText(left_time_text);
if (curr_obj->subtask_) {
m_print_gauge_progress->SetValue(curr_obj->subtask_->task_progress);
m_staticText_progress_percent->SetLabelText(wxString::Format("%d%%", curr_obj->subtask_->task_progress));
m_staticText_layers->SetLabelText(wxString::Format(_L("Layer: %d/%d"), curr_obj->curr_layer, curr_obj->total_layers));
}
else {
m_print_gauge_progress->SetValue(0);
m_staticText_progress_percent->SetLabelText(NA_STR);
m_staticText_layers->SetLabelText(wxString::Format(_L("Layer: %s"), NA_STR));
}
}
wxString subtask_text = wxString::Format("%s", GUI::from_u8(curr_obj->subtask_name));
if (curr_obj->get_modeltask() && curr_obj->get_modeltask()->design_id > 0) {
if (!m_staticText_profile_value->IsShown()) { m_staticText_profile_value->Show(); }
m_staticText_profile_value->SetLabelText(wxString::FromUTF8(curr_obj->get_modeltask()->profile_name));
}
else {
m_staticText_profile_value->SetLabelText(wxEmptyString);
m_staticText_profile_value->Hide();
}
}
else { // "IDLE" or
reset_printing_values();
}
m_print_panel->Layout();
m_print_panel->Thaw();
}
void CalibrationWizard::reset_printing_values()
{
m_button_pause_resume->Enable(false);
m_button_pause_resume->SetBitmap(m_bitmap_pause_disable.bmp());
m_button_abort->Enable(false);
m_button_abort->SetBitmap(m_bitmap_abort_disable.bmp());
m_btn_next->Enable(false);
m_staticText_profile_value->SetLabelText(wxEmptyString);
m_staticText_profile_value->Hide();
m_printing_stage_value->SetLabelText("");
m_print_gauge_progress->SetValue(0);
m_staticText_progress_left_time->SetLabelText(NA_STR);
m_staticText_layers->SetLabelText(wxString::Format(_L("Layer: %s"), NA_STR));
m_staticText_progress_percent->SetLabelText(NA_STR);
Layout();
}
void CalibrationWizard::on_subtask_pause_resume(wxCommandEvent& event)
{
if (curr_obj) {
if (curr_obj->can_resume())
curr_obj->command_task_resume();
else
curr_obj->command_task_pause();
}
}
void CalibrationWizard::on_subtask_abort(wxCommandEvent& event)
{
MessageDialog msg_dlg(nullptr, _L("Are you sure you want to cancel this calibration? It will return to start page"), wxEmptyString, wxICON_WARNING | wxOK | wxCANCEL);
if (msg_dlg.ShowModal() == wxID_OK) {
if (curr_obj) curr_obj->command_task_abort();
show_page(m_first_page);
save_to_printer_calib_info(PageType::Start);
Layout();
}
//if (abort_dlg == nullptr) {
// abort_dlg = new SecondaryCheckDialog(this->GetParent(), wxID_ANY, _L("Cancel print"));
// abort_dlg->Bind(EVT_SECONDARY_CHECK_CONFIRM, [this](wxCommandEvent& e) {
// if (obj) obj->command_task_abort();
// });
//}
//abort_dlg->update_text(_L("Are you sure you want to cancel this print?"));
//abort_dlg->on_show();
}
void CalibrationWizard::set_ams_select_mode(FilamentSelectMode mode) {
for (int i = 0; i < m_filament_comboBox_list.size(); i++) {
m_filament_comboBox_list[i]->set_select_mode(mode);
if (i >= 4)
m_filament_comboBox_list[i]->GetCheckBox()->Show(false);
}
}
std::vector<int> CalibrationWizard::get_selected_tray()
{
std::vector<int> tray_ids;
if (m_filament_from_ext_spool) {
if(m_virtual_tray_comboBox->GetRadioBox()->GetValue())
tray_ids.push_back(m_virtual_tray_comboBox->get_tray_id());
}
else {
if (get_ams_select_mode() == FilamentSelectMode::FSMCheckBoxMode) {
for (auto fcb : m_filament_comboBox_list) {
if (fcb->GetCheckBox()->GetValue()) {
tray_ids.push_back(fcb->get_tray_id());
}
}
}
else if (get_ams_select_mode() == FilamentSelectMode::FSMRadioMode) {
for (auto fcb : m_filament_comboBox_list) {
if (fcb->GetRadioBox()->GetValue()) {
tray_ids.push_back(fcb->get_tray_id());
}
}
}
}
return tray_ids;
}
FilamentComboBoxList CalibrationWizard::get_selected_filament_comboBox()
{
FilamentComboBoxList fcb_list;
if (m_filament_from_ext_spool) {
if (m_virtual_tray_comboBox->GetRadioBox()->GetValue())
fcb_list.push_back(m_virtual_tray_comboBox);
}
else {
if (get_ams_select_mode() == FilamentSelectMode::FSMCheckBoxMode) {
for (auto fcb : m_filament_comboBox_list) {
if (fcb->GetCheckBox()->GetValue()) {
fcb_list.push_back(fcb);
}
}
}
else if (get_ams_select_mode() == FilamentSelectMode::FSMRadioMode) {
for (auto fcb : m_filament_comboBox_list) {
if (fcb->GetRadioBox()->GetValue()) {
fcb_list.push_back(fcb);
}
}
}
}
return fcb_list;
}
void CalibrationWizard::init_presets_selections() {
init_nozzle_selections();
init_bed_type_selections();
init_process_selections();
}
void CalibrationWizard::init_nozzle_selections()
{
m_comboBox_nozzle_dia->Clear();
m_printer_preset = nullptr;
if (curr_obj) {
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.2));
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.4));
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.6));
m_comboBox_nozzle_dia->AppendString(wxString::Format("%1.1f", 0.8));
m_comboBox_nozzle_dia->SetSelection(-1);
m_comboBox_nozzle_dia->SetValue("");
}
}
void CalibrationWizard::init_bed_type_selections()
{
m_comboBox_bed_type->Clear();
int curr_selection = 0;
if (curr_obj) {
const ConfigOptionDef* bed_type_def = print_config_def.get("curr_bed_type");
if (bed_type_def && bed_type_def->enum_keys_map) {
for (auto item : bed_type_def->enum_labels) {
m_comboBox_bed_type->AppendString(_L(item));
}
m_comboBox_bed_type->SetSelection(curr_selection);
}
}
}
void CalibrationWizard::init_process_selections()
{
m_comboBox_process->Clear();
m_print_preset = nullptr;
wxArrayString print_items;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
double nozzle_value = 0.4;
wxString nozzle_value_str = m_comboBox_nozzle_dia->GetValue();
try {
nozzle_value_str.ToDouble(&nozzle_value);
}
catch (...) {
;
}
if (preset_bundle && curr_obj) {
for (auto print_it = preset_bundle->prints.begin(); print_it != preset_bundle->prints.end(); print_it++) {
ConfigOption* printer_opt = print_it->config.option("compatible_printers");
ConfigOptionStrings* printer_strs = dynamic_cast<ConfigOptionStrings*>(printer_opt);
for (auto printer_str : printer_strs->values) {
if (m_printer_preset && m_printer_preset->name == printer_str) {
wxString process_name = wxString::FromUTF8(print_it->name);
print_items.Add(process_name);
break;
}
}
}
m_comboBox_process->Set(print_items);
m_comboBox_process->SetSelection((print_items.size() + 1) / 2 - 1);
for (auto print_it = preset_bundle->prints.begin(); print_it != preset_bundle->prints.end(); print_it++) {
wxString print_name = wxString::FromUTF8(print_it->name);
if (print_name.compare(m_comboBox_process->GetValue()) == 0) {
m_print_preset = &*print_it;
}
}
}
}
void CalibrationWizard::update_printer() {
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
MachineObject* new_obj = dev->get_selected_machine();
if (new_obj) {
if (new_obj != curr_obj) {
curr_obj = new_obj;
wxGetApp().sidebar().load_ams_list(new_obj->dev_id, new_obj);
init_presets_selections();
change_ams_select_mode();
wxGetApp().preset_bundle->set_calibrate_printer("");
on_update_ams_filament(false);
on_switch_ams(m_ams_item_list[0]->m_amsinfo.ams_id);
for (auto fcb : m_filament_comboBox_list)
fcb->SetValue(false);
m_virtual_tray_comboBox->SetValue(false);
// for pa & flow rate calibration, need to change high end or low end pages
SimpleEvent e(EVT_CALIBRATION_NOTIFY_CHANGE_PAGES);
e.SetEventObject(this);
GetEventHandler()->ProcessEvent(e);
auto it = m_printer_calib_infos.find(curr_obj->dev_id);
if (it != m_printer_calib_infos.end() && it->second.mode == m_mode) {
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
if (filament_it->name == m_printer_calib_infos[curr_obj->dev_id].filament_preset) {
m_filament_preset = (&*filament_it);
}
}
}
jump_to_page(static_cast<PageType>(m_printer_calib_infos[curr_obj->dev_id].state));
}
else {
// reset to first page
show_page(m_first_page);
}
}
}
else {
curr_obj = nullptr;
}
}
void CalibrationWizard::on_select_nozzle(wxCommandEvent& evt) {
if (curr_obj) {
double nozzle_value = 0.0;
wxString nozzle_value_str = m_comboBox_nozzle_dia->GetValue();
try {
nozzle_value_str.ToDouble(&nozzle_value);
}
catch (...) {
;
}
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
for (auto printer_it = preset_bundle->printers.begin(); printer_it != preset_bundle->printers.end(); printer_it++) {
// only use system printer preset
if (!printer_it->is_system) continue;
ConfigOption* printer_nozzle_opt = printer_it->config.option("nozzle_diameter");
ConfigOptionFloats* printer_nozzle_vals = nullptr;
if (printer_nozzle_opt)
printer_nozzle_vals = dynamic_cast<ConfigOptionFloats*>(printer_nozzle_opt);
std::string model_id = printer_it->get_current_printer_type(preset_bundle);
if (model_id.compare(curr_obj->printer_type) == 0
&& printer_nozzle_vals
&& abs(printer_nozzle_vals->get_at(0) - nozzle_value) < 1e-3) {
m_printer_preset = &*printer_it;
}
}
if (m_printer_preset) {
preset_bundle->set_calibrate_printer(m_printer_preset->name);
on_update_ams_filament(false);
init_process_selections();
}
}
}
void CalibrationWizard::on_select_bed_type(wxCommandEvent& evt) {
recommend_input_value();
}
void CalibrationWizard::on_switch_ams(std::string ams_id)
{
for (auto i = 0; i < m_ams_item_list.size(); i++) {
AMSItem* item = m_ams_item_list[i];
if (item->m_amsinfo.ams_id == ams_id) {
item->OnSelected();
}
else {
item->UnSelected();
}
}
for (int i = 0; i < m_filament_comboBox_list.size(); i++) {
if (stoi(ams_id) * 4 <= i && i < stoi(ams_id) * 4 + 4)
m_filament_comboBox_list[i]->Show(true);
else {
m_filament_comboBox_list[i]->SetValue(false);
m_filament_comboBox_list[i]->Show(false);
}
}
Layout();
}
void CalibrationWizard::on_select_tray(SimpleEvent& evt) {
// when comboBox set selection or value of checkbox/radio changed will enter,
// check if preset names are same
FilamentComboBoxList fcb_list = get_selected_filament_comboBox();
if (fcb_list.empty()) {
m_filament_preset = nullptr;
m_filaments_incompatible_tips->SetLabel("");
m_filaments_incompatible_tips->Hide();
recommend_input_value();
return;
}
auto first_preset = fcb_list[0]->GetComboBox()->get_selected_preset();
if(!first_preset) {
m_filament_preset = nullptr;
recommend_input_value();
return;
}
bool all_preset_same = true;
for (auto fcb : fcb_list) {
auto selected_preset = fcb->GetComboBox()->get_selected_preset();
if (selected_preset && selected_preset->filament_id != first_preset->filament_id)
all_preset_same = false;
}
if (!all_preset_same) {
m_filament_preset = nullptr;
wxString tips = wxString(_L("filaments incompatible, please select same type of material"));
m_filaments_incompatible_tips->SetLabel(tips);
m_filaments_incompatible_tips->Show();
Layout();
}
else {
m_filament_preset = const_cast<Preset*>(first_preset);
m_filaments_incompatible_tips->SetLabel("");
m_filaments_incompatible_tips->Hide();
Layout();
}
set_save_name();
recommend_input_value();
}
void CalibrationWizard::on_update_ams_filament(bool dialog)
{
auto& list = wxGetApp().preset_bundle->filament_ams_list;
if (list.empty() && dialog) {
MessageDialog dlg(this, _L("No AMS filaments. Please select a printer to load AMS info."), _L("Sync filaments with AMS"), wxOK);
dlg.ShowModal();
return;
}
// clear selections while changing printer
for (auto& fcb : m_filament_comboBox_list)
fcb->update_from_preset();
m_virtual_tray_comboBox->update_from_preset();
// update tray info
DynamicPrintConfig empty_config;
empty_config.set_key_value("filament_id", new ConfigOptionStrings{ "" });
empty_config.set_key_value("tag_uid", new ConfigOptionStrings{ "" });
empty_config.set_key_value("filament_type", new ConfigOptionStrings{ "" });
empty_config.set_key_value("tray_name", new ConfigOptionStrings{ "" });
empty_config.set_key_value("filament_colour", new ConfigOptionStrings{ "" });
empty_config.set_key_value("filament_exist", new ConfigOptionBools{ false });
for (int i = 0; i < m_filament_comboBox_list.size(); i++) {
auto it = std::find_if(list.begin(), list.end(), [i](auto& entry) {
return entry.first == i;
});
if (it != list.end()) {
m_filament_comboBox_list[i]->load_tray_from_ams(i, it->second);
}
else {
m_filament_comboBox_list[i]->load_tray_from_ams(i, empty_config);
}
}
auto it = std::find_if(list.begin(), list.end(), [](auto& entry) {
return entry.first == VIRTUAL_TRAY_ID;
});
if (it != list.end()) {
m_virtual_tray_comboBox->load_tray_from_ams(VIRTUAL_TRAY_ID, it->second);
}
else {
m_virtual_tray_comboBox->load_tray_from_ams(VIRTUAL_TRAY_ID, empty_config);
}
// update m_ams_item_list
std::vector<AMSinfo> ams_info;
if (curr_obj) {
for (auto ams = curr_obj->amsList.begin(); ams != curr_obj->amsList.end(); ams++) {
AMSinfo info;
info.ams_id = ams->first;
if (ams->second->is_exists && info.parse_ams_info(ams->second, curr_obj->ams_calibrate_remain_flag, curr_obj->is_support_ams_humidity)) ams_info.push_back(info);
}
}
for (auto i = 0; i < m_ams_item_list.size(); i++) {
AMSItem* item = m_ams_item_list[i];
if (ams_info.size() > 1) {
m_muilti_ams_panel->Show();
if (i < ams_info.size()) {
item->Update(ams_info[i]);
item->Open();
}
else {
item->Close();
}
}
else {
m_muilti_ams_panel->Hide();
item->Close();
}
}
Layout();
}
bool CalibrationWizard::recommend_input_value() {
if (!m_filament_preset){
m_nozzle_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_bed_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_max_volumetric_speed->GetTextCtrl()->SetValue(wxEmptyString);
m_bed_type_incompatible_tips->SetLabel("");
m_bed_type_incompatible_tips->Hide();
return false;
}
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
int bed_temp_int = -1;
if (preset_bundle) {
// update nozzle temperature
ConfigOption* opt_nozzle_temp = m_filament_preset->config.option("nozzle_temperature");
if (opt_nozzle_temp) {
ConfigOptionInts* opt_min_ints = dynamic_cast<ConfigOptionInts*>(opt_nozzle_temp);
if (opt_min_ints) {
wxString text_nozzle_temp = wxString::Format("%d", opt_min_ints->get_at(0));
m_nozzle_temp->GetTextCtrl()->SetValue(text_nozzle_temp);
}
}
// update bed temperature
bed_temp_int = get_bed_temp(&m_filament_preset->config);
wxString bed_temp_text = wxString::Format("%d", bed_temp_int);
m_bed_temp->GetTextCtrl()->SetValue(bed_temp_text);
// update max flow speed
ConfigOption* opt_flow_speed = m_filament_preset->config.option("filament_max_volumetric_speed");
if (opt_flow_speed) {
ConfigOptionFloats* opt_flow_floats = dynamic_cast<ConfigOptionFloats*>(opt_flow_speed);
if (opt_flow_floats) {
wxString flow_val_text = wxString::Format("%0.2f", opt_flow_floats->get_at(0));
m_max_volumetric_speed->GetTextCtrl()->SetValue(flow_val_text);
}
}
// check compatibility
if (m_bed_temp->GetTextCtrl()->GetValue().compare("0") == 0) {
m_nozzle_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_bed_temp->GetTextCtrl()->SetValue(wxEmptyString);
m_max_volumetric_speed->GetTextCtrl()->SetValue(wxEmptyString);
wxString tips = wxString::Format(_L("%s does not support %s"), m_comboBox_bed_type->GetValue(), m_filament_preset->alias);
m_bed_type_incompatible_tips->SetLabel(tips);
m_bed_type_incompatible_tips->Update();
m_bed_type_incompatible_tips->Show();
Layout();
return false;
}
else {
m_bed_type_incompatible_tips->SetLabel("");
m_bed_type_incompatible_tips->Hide();
}
}
return true;
}
int CalibrationWizard::get_bed_temp(DynamicPrintConfig* config)
{
BedType curr_bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
const ConfigOptionInts* opt_bed_temp_ints = config->option<ConfigOptionInts>(get_bed_temp_key(curr_bed_type));
if (opt_bed_temp_ints) {
return opt_bed_temp_ints->get_at(0);
}
return -1;
}
bool CalibrationWizard::save_presets(const std::string& config_key, ConfigOption* config_value, const std::string& name)
{
auto filament_presets = &wxGetApp().preset_bundle->filaments;
DynamicPrintConfig* filament_config = &m_filament_preset->config;
bool save_to_project = false;
filament_config->set_key_value(config_key, config_value);
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
filament_presets->save_current_preset(name, false, save_to_project, m_filament_preset);
Preset* new_preset = filament_presets->find_preset(name, false, true);
if (!new_preset) {
BOOST_LOG_TRIVIAL(info) << "create new preset failed";
return false;
}
new_preset->sync_info = "create";
if (wxGetApp().is_user_login())
new_preset->user_id = wxGetApp().getAgent()->get_user_id();
BOOST_LOG_TRIVIAL(info) << "sync_preset: create preset = " << new_preset->name;
new_preset->save_info();
// Mark the print & filament enabled if they are compatible with the currently selected preset.
// If saving the preset changes compatibility with other presets, keep the now incompatible dependent presets selected, however with a "red flag" icon showing that they are no more compatible.
wxGetApp().preset_bundle->update_compatible(PresetSelectCompatibleType::Never);
// update current comboBox selected preset
std::string curr_preset_name = filament_presets->get_edited_preset().name;
wxGetApp().plater()->sidebar().update_presets_from_to(Preset::TYPE_FILAMENT, curr_preset_name, new_preset->name);
return true;
}
void CalibrationWizard::jump_to_page(PageType page_type) {
if (page_type == PageType::Finish) {
show_page(m_first_page);
return;
}
auto tabbook = static_cast<Tabbook*>(GetParent());
for (int i = 0; i < tabbook->GetPageCount(); i++) {
if (static_cast<CalibrationWizard*>(tabbook->GetPage(i))->get_calibration_mode() == m_mode)
tabbook->SetSelection(i);
}
auto page_node = m_first_page;
while (page_node)
{
if (page_node->get_page_type() == page_type) {
m_curr_page = page_node;
show_page(m_curr_page);
break;
}
page_node = page_node->get_next_page();
}
}
void CalibrationWizard::init_bitmaps()
{
m_bitmap_pause = ScalableBitmap(this, "print_control_pause", 18);
m_bitmap_pause_hover = ScalableBitmap(this, "print_control_pause_hover", 18);
m_bitmap_resume = ScalableBitmap(this, "print_control_resume", 18);
m_bitmap_resume_hover = ScalableBitmap(this, "print_control_resume_hover", 18);
m_bitmap_pause_disable = ScalableBitmap(this, "print_control_pause_disable", 18);
m_bitmap_resume_disable = ScalableBitmap(this, "print_control_resume_disable", 18);
m_bitmap_abort = ScalableBitmap(this, "print_control_stop", 18);
m_bitmap_abort_hover = ScalableBitmap(this, "print_control_stop_hover", 18);
m_bitmap_abort_disable = ScalableBitmap(this, "print_control_stop_disable", 18);
}
HistoryWindow::HistoryWindow(wxWindow* parent)
: DPIDialog(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
{
create();
wxGetApp().UpdateDlgDarkUI(this);
}
void HistoryWindow::create() {
this->SetBackgroundColour(*wxWHITE);
auto main_sizer = new wxBoxSizer(wxVERTICAL);
auto scroll_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL);
scroll_window->SetScrollRate(5, 5);
scroll_window->SetBackgroundColour(*wxWHITE);
auto scroll_sizer = new wxBoxSizer(wxVERTICAL);
scroll_window->SetSizer(scroll_sizer);
m_history_data_panel = new wxPanel(scroll_window);
scroll_sizer->Add(m_history_data_panel, 1, wxALIGN_CENTER);
main_sizer->Add(scroll_window, 1, wxEXPAND | wxALL, FromDIP(10));
SetSizer(main_sizer);
Layout();
Fit();
SetMinSize(wxSize(FromDIP(800), FromDIP(600)));
SetSize(wxSize(FromDIP(800), FromDIP(600)));
CenterOnParent();
}
PressureAdvanceWizard::PressureAdvanceWizard(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: CalibrationWizard(parent, CalibMode::Calib_PA_Line, id, pos, size, style)
{
create_pages();
init_bitmaps();
set_ams_select_mode(FSMCheckBoxMode);
Bind(EVT_CALIBRATION_NOTIFY_CHANGE_PAGES, &PressureAdvanceWizard::switch_pages, this);
m_page2->get_next_btn()->Bind(wxEVT_BUTTON, [this](auto& e) {
if (is_high_end_type(curr_obj))
request_calib_result(); // todo evaluate which ways : timer or button event
e.Skip();
});
}
void PressureAdvanceWizard::create_save_panel_content(wxBoxSizer* sizer)
{
// low end save panel
{
m_low_end_save_panel = new wxPanel(m_save_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
auto low_end_sizer = new wxBoxSizer(wxVERTICAL);
m_low_end_save_panel->SetSizer(low_end_sizer);
auto complete_text_panel = new wxPanel(m_low_end_save_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxBoxSizer* complete_text_sizer = new wxBoxSizer(wxVERTICAL);
auto complete_text = new wxStaticText(complete_text_panel, wxID_ANY, _L("Please find the best line on your plate"));
complete_text->SetFont(Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
complete_text_sizer->Add(complete_text, 0, wxALIGN_CENTER);
complete_text_panel->SetSizer(complete_text_sizer);
low_end_sizer->Add(complete_text_panel, 0, wxALIGN_CENTER, 0);
low_end_sizer->AddSpacer(FromDIP(20));
m_record_picture = new wxStaticBitmap(m_low_end_save_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
low_end_sizer->Add(m_record_picture, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 0);
low_end_sizer->AddSpacer(FromDIP(20));
auto value_sizer = new wxBoxSizer(wxHORIZONTAL);
auto k_value_text = new wxStaticText(m_low_end_save_panel, wxID_ANY, _L("Factor K"), wxDefaultPosition, wxDefaultSize, 0);
k_value_text->Wrap(-1);
k_value_text->SetFont(::Label::Body_14);
auto n_value_text = new wxStaticText(m_low_end_save_panel, wxID_ANY, _L("Factor N"), wxDefaultPosition, wxDefaultSize, 0);
n_value_text->Wrap(-1);
n_value_text->SetFont(::Label::Body_14);
m_k_val = new TextInput(m_low_end_save_panel, wxEmptyString, "", "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0);
m_n_val = new TextInput(m_low_end_save_panel, wxEmptyString, "", "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0);
n_value_text->Hide();
m_n_val->Hide();
value_sizer->Add(k_value_text, 0, wxALIGN_CENTER_VERTICAL, 0);
value_sizer->AddSpacer(FromDIP(10));
value_sizer->Add(m_k_val, 0);
value_sizer->AddSpacer(FromDIP(50));
value_sizer->Add(n_value_text, 0, wxALIGN_CENTER_VERTICAL, 0);
value_sizer->AddSpacer(FromDIP(10));
value_sizer->Add(m_n_val, 0);
low_end_sizer->Add(value_sizer, 0, wxALIGN_CENTER);
sizer->Add(m_low_end_save_panel, 0, wxEXPAND);
}
// high end save panel (Hide)
{
m_high_end_save_panel = new wxPanel(m_save_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
auto high_end_sizer = new wxBoxSizer(wxVERTICAL);
m_high_end_save_panel->SetSizer(high_end_sizer);
auto complete_text_panel = new wxPanel(m_high_end_save_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxBoxSizer* complete_text_sizer = new wxBoxSizer(wxVERTICAL);
auto complete_text = new wxStaticText(complete_text_panel, wxID_ANY, _L("We found the best Pressure Advance Factor"));
complete_text->SetFont(Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
complete_text_sizer->Add(complete_text, 0, wxALIGN_CENTER);
complete_text_panel->SetSizer(complete_text_sizer);
high_end_sizer->Add(complete_text_panel, 0, wxALIGN_CENTER, 0);
high_end_sizer->AddSpacer(FromDIP(20));
m_grid_panel = new wxPanel(m_high_end_save_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
high_end_sizer->Add(m_grid_panel, 0, wxALIGN_CENTER);
sizer->Add(m_high_end_save_panel, 0, wxEXPAND);
m_high_end_save_panel->Hide();
}
}
CalibrationWizardPage* PressureAdvanceWizard::create_start_page()
{
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Start);
page->set_highlight_step_text(PageType::Start);
auto page_content_sizer = page->get_content_vsizer();
auto when_title = new wxStaticText(page, wxID_ANY, _L("When you need Pressure Advance Calibration"));
when_title->SetFont(Label::Head_14);
when_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_title);
auto when_text = new wxStaticText(page, wxID_ANY, _L("uneven extrusion"));
when_text->SetFont(Label::Body_14);
when_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text);
page_content_sizer->AddSpacer(PRESET_GAP);
auto bitmap_sizer = new wxBoxSizer(wxHORIZONTAL);
auto bitmap1 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap1->SetMinSize(wxSize(560, 450));
bitmap1->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap1, 0, wxALL, 0);
bitmap_sizer->AddSpacer(FromDIP(20));
auto bitmap2 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap2->SetMinSize(wxSize(560, 450));
bitmap2->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap2, 0, wxALL, 0);
page_content_sizer->Add(bitmap_sizer, 0, wxALL, 0);
page_content_sizer->AddSpacer(PRESET_GAP);
auto about_title = new wxStaticText(page, wxID_ANY, _L("About this calibration"));
about_title->SetFont(Label::Head_14);
about_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(about_title);
auto about_text = new wxStaticText(page, wxID_ANY, _L("After calibration, the linear compensation factor(K) will be recorded and applied to printing. This factor would be different if device, degree of usage, material, and material family type are different"));
about_text->SetFont(Label::Body_14);
about_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(about_text);
page_content_sizer->AddSpacer(PRESET_GAP);
auto wiki = new wxStaticText(page, wxID_ANY, _L("Wiki"));
wiki->SetFont(Label::Head_14);
wiki->SetForegroundColour({ 0, 88, 220 });
wiki->Bind(wxEVT_ENTER_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_HAND);
});
wiki->Bind(wxEVT_LEAVE_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_ARROW);
});
wiki->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty()) wxLaunchDefaultBrowser(m_wiki_url);
});
page_content_sizer->Add(wiki, 0);
auto page_prev_btn = page->get_prev_btn();
page_prev_btn->Hide();
page_prev_btn->SetLabel(_L("Manage Result"));
page_prev_btn->SetButtonType(ButtonType::Back);
page_prev_btn->Bind(wxEVT_BUTTON, [this](auto& e) {
if (is_high_end_type(curr_obj)) {
// todo emit once and loop to get
CalibUtils::emit_get_PA_calib_infos();
CalibUtils::get_PA_calib_tab(m_calib_results_history);
sync_history_window_data();
}
m_history_page->ShowModal();
});
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Start"));
page_next_btn->SetButtonType(ButtonType::Start);
return page;
}
void PressureAdvanceWizard::create_pages()
{
create_history_window();
// page 0 : start page
m_page0 = create_start_page();
m_page0->set_page_title(_L("Pressure Advance"));
m_all_pages_sizer->Add(m_page0, 1, wxEXPAND | wxALL, FromDIP(25));
// page 1 : preset page
m_page1 = create_presets_page(false);
m_page1->set_page_title(_L("Pressure Advance"));
m_all_pages_sizer->Add(m_page1, 1, wxEXPAND | wxALL, FromDIP(25));
// page 2 : print page
m_page2 = create_print_page();
m_page2->set_page_title(_L("Pressure Advance"));
m_all_pages_sizer->Add(m_page2, 1, wxEXPAND | wxALL, FromDIP(25));
// page 3 : save page
m_page3 = create_save_page();
m_page3->set_page_title(_L("Pressure Advance"));
m_all_pages_sizer->Add(m_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// link page
m_first_page = m_page0;
m_curr_page = m_page0;
m_page0->chain(m_page1)->chain(m_page2)->chain(m_page3);
show_page(m_curr_page);
}
void PressureAdvanceWizard::create_history_window()
{
m_history_page = new HistoryWindow(this);
}
void PressureAdvanceWizard::request_calib_result() {
// todo emit once and loop to get
if (is_high_end_type(curr_obj)) {
CalibUtils::emit_get_PA_calib_results();
CalibUtils::get_PA_calib_results(m_calib_results);
CalibUtils::emit_get_PA_calib_infos();
CalibUtils::get_PA_calib_tab(m_calib_results_history);
// todo if failed to get result
// pass m_calib_results info to page3
if (m_calib_results.size() > 0)
sync_save_page_data();
}
}
void PressureAdvanceWizard::sync_history_window_data() {
auto history_data_panel = m_history_page->m_history_data_panel;
history_data_panel->DestroyChildren();
wxFlexGridSizer* fgSizer;
fgSizer = new wxFlexGridSizer(0, 5, FromDIP(10), FromDIP(80));
fgSizer->SetFlexibleDirection(wxBOTH);
fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
history_data_panel->SetSizer(fgSizer, true);
auto title_nozzle = new wxStaticText(history_data_panel, wxID_ANY, _L("Nozzle Diameter"));
title_nozzle->SetFont(Label::Head_14);
fgSizer->Add(title_nozzle);
auto title_material = new wxStaticText(history_data_panel, wxID_ANY, _L("Material"));
title_material->SetFont(Label::Head_14);
fgSizer->Add(title_material);
auto title_k = new wxStaticText(history_data_panel, wxID_ANY, _L("K"));
title_k->SetFont(Label::Head_14);
fgSizer->Add(title_k);
auto title_n = new wxStaticText(history_data_panel, wxID_ANY, _L("N"));
title_n->SetFont(Label::Head_14);
fgSizer->Add(title_n);
auto title_action = new wxStaticText(history_data_panel, wxID_ANY, _L("Action"));
title_action->SetFont(Label::Head_14);
fgSizer->Add(title_action);
for (auto result : m_calib_results_history) {
auto nozzle_dia_value = new wxStaticText(history_data_panel, wxID_ANY, std::to_string(result.nozzle_diameter));
wxString material_name = NA_STR;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
for (auto filament_it = preset_bundle->filaments.begin(); filament_it != preset_bundle->filaments.end(); filament_it++) {
if (filament_it->setting_id == result.setting_id) {
material_name = filament_it->label(false);
}
}
}
auto material_name_value = new wxStaticText(history_data_panel, wxID_ANY, material_name);
auto k_value = new wxStaticText(history_data_panel, wxID_ANY, std::to_string(result.k_value));
auto n_value = new wxStaticText(history_data_panel, wxID_ANY, std::to_string(result.n_coef));
auto delete_button = new wxButton(history_data_panel, wxID_ANY, _L("Delete"));
delete_button->Bind(wxEVT_BUTTON, [this](auto &e) {
// todo delete m_calib_results_history item
;
});
fgSizer->Add(material_name_value);
fgSizer->Add(k_value);
fgSizer->Add(n_value);
fgSizer->Add(delete_button);
}
if (m_calib_results_history.empty()) {
// todo show empty UI
}
m_history_page->Layout();
}
void PressureAdvanceWizard::sync_save_page_data() {
FilamentComboBoxList fcb_list = get_selected_filament_comboBox();
m_grid_panel->DestroyChildren();
wxBoxSizer* grid_sizer = new wxBoxSizer(wxHORIZONTAL);
const int COLUMN_GAP = FromDIP(50);
const int ROW_GAP = FromDIP(30);
wxBoxSizer* left_title_sizer = new wxBoxSizer(wxVERTICAL);
left_title_sizer->AddSpacer(FromDIP(49));
auto k_title = new wxStaticText(m_grid_panel, wxID_ANY, _L("FactorK"), wxDefaultPosition, wxDefaultSize, 0);
k_title->SetFont(Label::Head_14);
left_title_sizer->Add(k_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto n_title = new wxStaticText(m_grid_panel, wxID_ANY, _L("FactorN"), wxDefaultPosition, wxDefaultSize, 0);
n_title->SetFont(Label::Head_14);
left_title_sizer->Add(n_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto brand_title = new wxStaticText(m_grid_panel, wxID_ANY, _L("Brand Name"), wxDefaultPosition, wxDefaultSize, 0);
brand_title->SetFont(Label::Head_14);
left_title_sizer->Add(brand_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
grid_sizer->Add(left_title_sizer);
grid_sizer->AddSpacer(COLUMN_GAP);
for (auto fcb : fcb_list) {
wxBoxSizer* column_data_sizer = new wxBoxSizer(wxVERTICAL);
auto tray_title = new wxStaticText(m_grid_panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
tray_title->SetFont(Label::Head_14);
tray_title->SetLabel(fcb->get_tray_name());
column_data_sizer->Add(tray_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto k_value = new wxStaticText(m_grid_panel, wxID_ANY, NA_STR, wxDefaultPosition, wxDefaultSize, 0);
auto n_value = new wxStaticText(m_grid_panel, wxID_ANY, NA_STR, wxDefaultPosition, wxDefaultSize, 0);
for (auto calib_result : m_calib_results) {
if (calib_result.tray_id == fcb->get_tray_id()) {
k_value->SetLabel(std::to_string(calib_result.k_value));
n_value->SetLabel(std::to_string(calib_result.n_coef));
}
}
column_data_sizer->Add(k_value, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
column_data_sizer->Add(n_value, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
if (fcb->is_bbl_filament()) {
auto comboBox_tray_name = new TextInput(m_grid_panel, fcb->GetComboBox()->GetValue(), "", "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE, wxTE_READONLY | wxTE_CENTER);
comboBox_tray_name->SetBorderWidth(0);
comboBox_tray_name->GetTextCtrl()->Bind(wxEVT_SET_FOCUS, [](auto&) {});
column_data_sizer->Add(comboBox_tray_name, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
}
else {
auto comboBox_tray_name = new ComboBox(m_grid_panel, wxID_ANY, "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE);
wxArrayString selections;
for (auto history : m_calib_results_history) {
if (history.tray_id == fcb->get_tray_id())
selections.push_back(history.name);
}
comboBox_tray_name->Set(selections);
comboBox_tray_name->SetValue(fcb->GetComboBox()->GetValue());
comboBox_tray_name->GetTextCtrl()->Bind(wxEVT_KEY_DOWN, [this, fcb, comboBox_tray_name](auto& e) {
if (wxGetKeyState(WXK_RETURN)) {
auto it = std::find_if(m_calib_results.begin(), m_calib_results.end(), [fcb](auto& calib_result) {
return calib_result.tray_id == fcb->get_tray_id();
});
if (it != m_calib_results.end())
it->name = comboBox_tray_name->GetTextCtrl()->GetValue().ToStdString();
}
else
e.Skip();
});
column_data_sizer->Add(comboBox_tray_name, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
}
grid_sizer->Add(column_data_sizer);
grid_sizer->AddSpacer(COLUMN_GAP);
}
m_grid_panel->SetSizer(grid_sizer, true);
Layout();
}
void PressureAdvanceWizard::switch_pages(SimpleEvent& evt) {
if (curr_obj) {
if (is_high_end_type(curr_obj))
{
m_low_end_save_panel->Hide();
m_high_end_save_panel->Show();
m_page0->get_prev_btn()->Show();
sync_save_page_data(); // CALIBRATION_DEBUG
}
else
{
m_high_end_save_panel->Hide();
m_low_end_save_panel->Show();
m_page0->get_prev_btn()->Hide();
}
Layout();
}
}
void PressureAdvanceWizard::change_ams_select_mode() {
if (is_high_end_type(curr_obj)) {
set_ams_select_mode(FSMCheckBoxMode);
}
else{
set_ams_select_mode(FSMRadioMode);
}
}
bool PressureAdvanceWizard::start_calibration(std::vector<int> tray_ids)
{
int nozzle_temp = -1;
int bed_temp = -1;
float max_volumetric_speed = -1;
nozzle_temp = stoi(m_nozzle_temp->GetTextCtrl()->GetValue().ToStdString());
bed_temp = stoi(m_bed_temp->GetTextCtrl()->GetValue().ToStdString());
max_volumetric_speed = stof(m_max_volumetric_speed->GetTextCtrl()->GetValue().ToStdString());
if (bed_temp < 0 || nozzle_temp < 0 || max_volumetric_speed < 0) {
MessageDialog msg_dlg(nullptr, _L("Make sure bed_temp > 0 \nnozzle_temp > 0\nmax_volumetric_speed > 0"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
if (is_high_end_type(curr_obj)) {
m_calib_results.clear();
X1CCalibInfos calib_infos;
for (int tray_id : tray_ids) {
X1CCalibInfos::X1CCalibInfo calib_info;
calib_info.tray_id = tray_id;
calib_info.nozzle_diameter = dynamic_cast<ConfigOptionFloats *>(m_printer_preset->config.option("nozzle_diameter"))->get_at(0);
calib_info.filament_id = m_filament_preset->filament_id;
calib_info.setting_id = m_filament_preset->setting_id;
calib_info.bed_temp = bed_temp;
calib_info.nozzle_temp = nozzle_temp;
calib_info.max_volumetric_speed = max_volumetric_speed;
calib_infos.calib_datas.push_back(calib_info);
}
std::string error_message;
CalibUtils::calib_PA(calib_infos, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, error_message, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_page(get_curr_page()->get_next_page());
return true;
}
else {
curr_obj->command_start_extrusion_cali(tray_ids[0], nozzle_temp, bed_temp, max_volumetric_speed, m_filament_preset->setting_id);
show_page(get_curr_page()->get_next_page());
return true;
}
return false;
}
bool PressureAdvanceWizard::save_calibration_result()
{
if (is_high_end_type(curr_obj)) {
CalibUtils::set_PA_calib_result(m_calib_results);
MessageDialog msg_dlg(nullptr, _L("Saved success."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
m_calib_results.clear();
m_calib_results.shrink_to_fit();
return true;
}
else {
auto check_k_validation = [](wxString k_text)
{
if (k_text.IsEmpty())
return false;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
if (k < 0 || k > 0.5)
return false;
return true;
};
auto check_k_n_validation = [](wxString k_text, wxString n_text)
{
if (k_text.IsEmpty() || n_text.IsEmpty())
return false;
double k = 0.0;
try {
k_text.ToDouble(&k);
}
catch (...) {
;
}
double n = 0.0;
try {
n_text.ToDouble(&n);
}
catch (...) {
;
}
if (k < 0 || k > 0.5)
return false;
if (n < 0.6 || n > 2.0)
return false;
return true;
};
wxString k_text = m_k_val->GetTextCtrl()->GetValue();
wxString n_text = m_n_val->GetTextCtrl()->GetValue();
if (!check_k_validation(k_text)) {
wxString k_tips = _L("Please input a valid value (K in 0~0.5)");
//wxString kn_tips = _L("Please input a valid value (K in 0~0.5, N in 0.6~2.0)");
MessageDialog msg_dlg(nullptr, k_tips, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
double k = 0.0;
k_text.ToDouble(&k);
double n = 0.0;
//n_text.ToDouble(&n);
// set values
int nozzle_temp = -1;
int bed_temp = -1;
float max_volumetric_speed = -1;
std::string setting_id;
std::string name;
nozzle_temp = stoi(m_nozzle_temp->GetTextCtrl()->GetValue().ToStdString());
bed_temp = stoi(m_bed_temp->GetTextCtrl()->GetValue().ToStdString());
max_volumetric_speed = stof(m_max_volumetric_speed->GetTextCtrl()->GetValue().ToStdString());
setting_id = m_filament_preset->setting_id;
name = m_filament_preset->name;
// send command
std::vector<int> tray_ids = get_selected_tray();
curr_obj->command_extrusion_cali_set(tray_ids[0], setting_id, name, k, n, bed_temp, nozzle_temp, max_volumetric_speed);
MessageDialog msg_dlg(nullptr, _L("Saved success."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return true;
}
return false;
}
bool PressureAdvanceWizard::recommend_input_value()
{
return CalibrationWizard::recommend_input_value();
}
void PressureAdvanceWizard::init_bitmaps()
{
m_print_picture->SetBitmap(create_scaled_bitmap("extrusion_calibration_tips_en", nullptr, 400));
m_record_picture->SetBitmap(create_scaled_bitmap("extrusion_calibration_tips_en", nullptr, 400));
}
FlowRateWizard::FlowRateWizard(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: CalibrationWizard(parent, CalibMode::Calib_Flow_Rate, id, pos, size, style)
{
create_pages();
init_bitmaps();
Bind(EVT_CALIBRATION_NOTIFY_CHANGE_PAGES, &FlowRateWizard::switch_pages, this);
}
void FlowRateWizard::set_save_name() {
if (m_filament_preset) {
m_save_name = m_filament_preset->alias + "-Calibrated";
}
else { m_save_name = ""; }
if (!is_high_end_type(curr_obj)) {
m_save_name_input1->GetTextCtrl()->SetValue(m_save_name);
m_save_name_input2->GetTextCtrl()->SetValue(m_save_name);
}
}
void FlowRateWizard::create_save_panel_content(wxBoxSizer* sizer)
{
auto complete_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Please find the best object on your plate"), wxDefaultPosition, wxDefaultSize, 0);
complete_text->SetFont(Label::Head_14);
complete_text->Wrap(-1);
sizer->Add(complete_text, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
m_low_record_picture2 = new wxStaticBitmap(m_save_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
m_low_record_picture2->SetMinSize(wxSize(560, 450));
m_low_record_picture2->SetBackgroundColour(*wxBLACK);
sizer->Add(m_low_record_picture2, 0, wxALIGN_CENTER, 0);
sizer->AddSpacer(FromDIP(20));
auto fine_value_sizer = new wxBoxSizer(wxVERTICAL);
auto fine_value_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Fill in the value above the block with smoothest top surface"), wxDefaultPosition, wxDefaultSize, 0);
fine_value_text->Wrap(-1);
fine_value_text->SetFont(::Label::Head_14);
m_optimal_block_fine = new ComboBox(m_save_panel, wxID_ANY, "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0, nullptr, wxCB_READONLY);
wxArrayString fine_block_items;
for (int i = 0; i < 10; i++)
{
fine_block_items.Add(std::to_string(-9 + (i)));
}
m_optimal_block_fine->Set(fine_block_items);
m_fine_calc_result_text = new wxStaticText(m_save_panel, wxID_ANY, "");
fine_value_sizer->Add(fine_value_text, 0, 0);
fine_value_sizer->Add(m_optimal_block_fine, 0, 0);
fine_value_sizer->Add(m_fine_calc_result_text, 0);
sizer->Add(fine_value_sizer, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
auto save_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Save to Filament Preset"), wxDefaultPosition, wxDefaultSize, 0);
save_text->Wrap(-1);
save_text->SetFont(Label::Head_14);
sizer->Add(save_text, 0, 0, 0);
m_save_name_input2 = new TextInput(m_save_panel, m_save_name, "", "", wxDefaultPosition, { CALIBRATION_TEXT_MAX_LENGTH, FromDIP(24) }, 0);
sizer->Add(m_save_name_input2, 0, 0, 0);
m_save_name_input2->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_save_name_input2->GetTextCtrl()->GetValue().IsEmpty())
m_save_name = m_save_name_input2->GetTextCtrl()->GetValue().ToStdString();
else
m_save_name = "";
});
}
void FlowRateWizard::create_low_end_pages() {
// page 3 : save coarse result
m_low_end_page3 = new CalibrationWizardPage(m_scrolledWindow, false);
m_low_end_page3->set_page_title(_L("Flow Rate"));
m_low_end_page3->set_page_type(PageType::CoarseSave);
m_low_end_page3->set_highlight_step_text(PageType::CoarseSave);
auto page3_content_sizer = m_low_end_page3->get_content_vsizer();
auto page3_description = new wxStaticText(m_low_end_page3, wxID_ANY, _L("Please find the best object on your plate"), wxDefaultPosition, wxDefaultSize, 0);
page3_description->SetFont(Label::Head_14);
page3_description->Wrap(-1);
page3_content_sizer->Add(page3_description, 0, 0, 0);
page3_content_sizer->AddSpacer(FromDIP(20));
m_low_record_picture1 = new wxStaticBitmap(m_low_end_page3, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
m_low_record_picture1->SetMinSize(wxSize(560, 450));
m_low_record_picture1->SetBackgroundColour(*wxBLACK);
page3_content_sizer->Add(m_low_record_picture1, 0, 0, 0);
page3_content_sizer->AddSpacer(FromDIP(20));
auto coarse_value_sizer = new wxBoxSizer(wxVERTICAL);
auto coarse_value_text = new wxStaticText(m_low_end_page3, wxID_ANY, _L("Fill in the value above the block with smoothest top surface"), wxDefaultPosition, wxDefaultSize, 0);
coarse_value_text->SetFont(Label::Head_14);
coarse_value_text->Wrap(-1);
m_optimal_block_coarse = new ComboBox(m_low_end_page3, wxID_ANY, "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0, nullptr, wxCB_READONLY);
wxArrayString coarse_block_items;
for (int i = 0; i < 9; i++)
{
coarse_block_items.Add(std::to_string(-20 + (i * 5)));
}
m_optimal_block_coarse->Set(coarse_block_items);
m_coarse_calc_result_text = new wxStaticText(m_low_end_page3, wxID_ANY, "");
coarse_value_sizer->Add(coarse_value_text, 0, 0);
coarse_value_sizer->Add(m_optimal_block_coarse, 0, 0);
coarse_value_sizer->Add(m_coarse_calc_result_text, 0);
page3_content_sizer->Add(coarse_value_sizer, 0, 0, 0);
page3_content_sizer->AddSpacer(FromDIP(20));
auto checkBox_panel = new wxPanel(m_low_end_page3);
auto cb_sizer = new wxBoxSizer(wxHORIZONTAL);
checkBox_panel->SetSizer(cb_sizer);
m_checkBox_skip_calibration = new CheckBox(checkBox_panel);
cb_sizer->Add(m_checkBox_skip_calibration);
auto cb_text = new wxStaticText(checkBox_panel, wxID_ANY, _L("Skip Calibration2"));
cb_sizer->Add(cb_text);
cb_text->Bind(wxEVT_LEFT_DOWN, [this](auto &) {
m_checkBox_skip_calibration->SetValue(!m_checkBox_skip_calibration->GetValue());
wxCommandEvent event(wxEVT_TOGGLEBUTTON);
event.SetEventObject(m_checkBox_skip_calibration);
m_checkBox_skip_calibration->GetEventHandler()->ProcessEvent(event);
});
page3_content_sizer->Add(checkBox_panel, 0, 0, 0);
auto save_panel = new wxPanel(m_low_end_page3);
auto save_sizer = new wxBoxSizer(wxVERTICAL);
save_panel->SetSizer(save_sizer);
auto save_text = new wxStaticText(save_panel, wxID_ANY, _L("Save to Filament Preset"), wxDefaultPosition, wxDefaultSize, 0);
save_text->Wrap(-1);
save_text->SetFont(Label::Head_14);
save_sizer->Add(save_text, 0, 0, 0);
m_save_name_input1 = new TextInput(save_panel, m_save_name, "", "", wxDefaultPosition, { CALIBRATION_TEXT_MAX_LENGTH, FromDIP(24) }, 0);
save_sizer->Add(m_save_name_input1, 0, 0, 0);
m_save_name_input1->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_save_name_input1->GetTextCtrl()->GetValue().IsEmpty())
m_save_name = m_save_name_input1->GetTextCtrl()->GetValue().ToStdString();
else
m_save_name = "";
});
page3_content_sizer->Add(save_panel, 0, 0, 0);
save_panel->Hide();
auto page3_prev_btn = m_low_end_page3->get_prev_btn();
page3_prev_btn->Hide();
auto page3_next_btn = m_low_end_page3->get_next_btn();
page3_next_btn->SetLabel(_L("Calibrate"));
page3_next_btn->SetButtonType(ButtonType::Calibrate);
m_checkBox_skip_calibration->Bind(wxEVT_TOGGLEBUTTON, [this, save_panel](auto& e) {
if (m_checkBox_skip_calibration->GetValue()) {
m_low_end_page3->get_next_btn()->SetLabel(_L("Save"));
m_low_end_page3->get_next_btn()->SetButtonType(ButtonType::Save);
save_panel->Show();
}
else {
m_low_end_page3->get_next_btn()->SetLabel(_L("Calibrate"));
m_low_end_page3->get_next_btn()->SetButtonType(ButtonType::Calibrate);
save_panel->Hide();
m_low_end_page3->get_next_btn()->Bind(wxEVT_BUTTON, &FlowRateWizard::on_fine_tune, this);
}
Layout();
e.Skip();
});
m_all_pages_sizer->Add(m_low_end_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// page 4 : print page
m_low_end_page4 = new CalibrationWizardPage(m_scrolledWindow, true);
m_low_end_page4->set_page_title(_L("Flow Rate"));
m_low_end_page4->set_page_type(PageType::FineCalibration);
m_low_end_page4->set_highlight_step_text(PageType::FineCalibration);
m_low_end_page4->get_prev_btn()->Hide();
auto page4_next_btn = m_low_end_page4->get_next_btn();
page4_next_btn->SetLabel(_L("Next"));
page4_next_btn->SetButtonType(ButtonType::Next);
auto page4_content_sizer = m_low_end_page4->get_content_vsizer();
m_low_print_picture2 = new wxStaticBitmap(m_low_end_page4, wxID_ANY, create_scaled_bitmap("flow_rate_calibration_fine", nullptr, 400), wxDefaultPosition, wxDefaultSize, 0);
page4_content_sizer->Add(m_low_print_picture2, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 0);
page4_content_sizer->AddSpacer(FromDIP(20));
m_all_pages_sizer->Add(m_low_end_page4, 1, wxEXPAND | wxALL, FromDIP(25));
// page 5 : save fine result
m_low_end_page5 = create_save_page();
m_low_end_page5->set_page_title(_L("Flow Rate"));
m_all_pages_sizer->Add(m_low_end_page5, 1, wxEXPAND | wxALL, FromDIP(25));
// link page
m_page2->chain(m_low_end_page3)->chain(m_low_end_page4)->chain(m_low_end_page5);
show_page(m_curr_page);
m_optimal_block_coarse->Bind(wxEVT_COMBOBOX, [this](auto& e) {
if (m_filament_preset) {
DynamicPrintConfig& filament_config = m_filament_preset->config;
auto curr_flow_ratio = filament_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
m_coarse_calc_result = curr_flow_ratio * (100.0f + stof(m_optimal_block_coarse->GetValue().ToStdString())) / 100.0f;
m_coarse_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_coarse_calc_result)));
}
});
m_optimal_block_fine->Bind(wxEVT_COMBOBOX, [this](auto& e) {
if (m_filament_preset) {
DynamicPrintConfig& filament_config = m_filament_preset->config;
auto curr_flow_ratio = filament_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
m_fine_calc_result = curr_flow_ratio * (100.0f + stof(m_optimal_block_fine->GetValue().ToStdString())) / 100.0f;
m_fine_calc_result_text->SetLabel(wxString::Format(_L("flow ratio : %s "), std::to_string(m_fine_calc_result)));
}
});
}
void FlowRateWizard::create_high_end_pages() {
// page 3 : save fine result
m_high_end_page3 = new CalibrationWizardPage(m_scrolledWindow, false);
m_high_end_page3->set_page_title(_L("Flow Rate"));
m_high_end_page3->set_page_type(PageType::Save);
m_high_end_page3->set_highlight_step_text(PageType::Save);
auto high_end_page3_content_sizer = m_high_end_page3->get_content_vsizer();
auto complete_text_panel = new wxPanel(m_high_end_page3, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
wxBoxSizer* complete_text_sizer = new wxBoxSizer(wxVERTICAL);
auto complete_text = new wxStaticText(complete_text_panel, wxID_ANY, _L("We found the best flow ratio for you"));
complete_text->SetFont(Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
complete_text_sizer->Add(complete_text, 0, wxALIGN_CENTER);
complete_text_panel->SetSizer(complete_text_sizer);
high_end_page3_content_sizer->Add(complete_text_panel, 0, wxALIGN_CENTER, 0);
high_end_page3_content_sizer->AddSpacer(FromDIP(20));
m_grid_panel = new wxPanel(m_high_end_page3, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
high_end_page3_content_sizer->Add(m_grid_panel, 0, wxALIGN_CENTER);
auto high_end_page3_prev_btn = m_high_end_page3->get_prev_btn();
high_end_page3_prev_btn->Hide();
auto high_end_page3_next_btn = m_high_end_page3->get_next_btn();
high_end_page3_next_btn->SetLabel(_L("Save"));
high_end_page3_next_btn->SetButtonType(ButtonType::Save);
m_all_pages_sizer->Add(m_high_end_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// link page
m_page2->chain(m_high_end_page3);
show_page(m_curr_page);
m_page2->get_next_btn()->Bind(wxEVT_BUTTON, [this](auto& e) {
if (is_high_end_type(curr_obj))
request_calib_result(); // todo evaluate which ways : timer or button event
e.Skip();
});
}
CalibrationWizardPage* FlowRateWizard::create_start_page()
{
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Start);
page->set_highlight_step_text(PageType::Start);
auto page_content_sizer = page->get_content_vsizer();
auto when_title = new wxStaticText(page, wxID_ANY, _L("When you need Flow Rate Calibration"));
when_title->SetFont(Label::Head_14);
when_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_title);
auto when_text = new wxStaticText(page, wxID_ANY, _L("Over-extrusion or under extrusion"));
when_text->SetFont(Label::Body_14);
when_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text);
page_content_sizer->AddSpacer(PRESET_GAP);
auto recommend_title = new wxStaticText(page, wxID_ANY, _L("Flow Rate calibration is recommended when you print with:"));
recommend_title->SetFont(Label::Head_14);
recommend_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(recommend_title);
auto recommend_text1 = new wxStaticText(page, wxID_ANY, _L("material with significant thermal shrinkage/expansion, such as..."));
recommend_text1->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
recommend_text1->SetFont(Label::Body_14);
page_content_sizer->Add(recommend_text1);
auto recommend_text2 = new wxStaticText(page, wxID_ANY, _L("materials with inaccurate filament diameter"));
recommend_text2->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
recommend_text2->SetFont(Label::Body_14);
page_content_sizer->Add(recommend_text2);
page_content_sizer->AddSpacer(PRESET_GAP);
auto bitmap_sizer = new wxBoxSizer(wxHORIZONTAL);
auto bitmap1 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap1->SetMinSize(wxSize(560, 450));
bitmap1->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap1, 0, wxALL, 0);
bitmap_sizer->AddSpacer(FromDIP(20));
auto bitmap2 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap2->SetMinSize(wxSize(560, 450));
bitmap2->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap2, 0, wxALL, 0);
page_content_sizer->Add(bitmap_sizer, 0, wxALL, 0);
page_content_sizer->AddSpacer(PRESET_GAP);
auto wiki = new wxStaticText(page, wxID_ANY, _L("Wiki")); //todo set wiki url
wiki->SetFont(Label::Head_14);
wiki->SetForegroundColour({ 0, 88, 220 });
wiki->Bind(wxEVT_ENTER_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_HAND);
});
wiki->Bind(wxEVT_LEAVE_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_ARROW);
});
wiki->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty()) wxLaunchDefaultBrowser(m_wiki_url);
});
page_content_sizer->Add(wiki, 0);
page->get_prev_btn()->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Start"));
page_next_btn->SetButtonType(ButtonType::Start);
return page;
}
void FlowRateWizard::create_pages()
{
// page 0 : start page
m_page0 = create_start_page();
m_page0->set_page_title(_L("Flow Rate"));
m_all_pages_sizer->Add(m_page0, 1, wxEXPAND | wxALL, FromDIP(25));
// page 1 : preset page
m_page1 = create_presets_page(false);
m_page1->set_page_title(_L("Flow Rate"));
// Hide
{
auto page1_content_sizer = m_page1->get_content_vsizer();
m_choose_step_panel = new wxPanel(m_page1);
auto choose_step_sizer = new wxBoxSizer(wxVERTICAL);
m_choose_step_panel->SetSizer(choose_step_sizer);
m_complete_radioBox = new wxRadioButton(m_choose_step_panel, wxID_ANY, _L("Complete Calibration"));
m_complete_radioBox->SetValue(true);
choose_step_sizer->Add(m_complete_radioBox);
choose_step_sizer->AddSpacer(FromDIP(10));
m_fine_radioBox = new wxRadioButton(m_choose_step_panel, wxID_ANY, _L("Fine Calibration based on flow ratio"));
choose_step_sizer->Add(m_fine_radioBox);
choose_step_sizer->AddSpacer(FromDIP(10));
TextInput* flow_ratio_input = new TextInput(m_choose_step_panel, wxEmptyString,"", "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE);
flow_ratio_input->Hide();
choose_step_sizer->Add(flow_ratio_input, 0, wxLEFT, FromDIP(18));
flow_ratio_input->GetTextCtrl()->Bind(wxEVT_TEXT, [this, flow_ratio_input](auto& e) {
if (flow_ratio_input->GetTextCtrl()->GetValue().IsEmpty())
flow_ratio_input->GetTextCtrl()->SetValue("1");
m_coarse_calc_result = stof(flow_ratio_input->GetTextCtrl()->GetValue().ToStdString());
});
m_complete_radioBox->Bind(wxEVT_RADIOBUTTON, [this, flow_ratio_input](auto& e) {
flow_ratio_input->Show(m_fine_radioBox->GetValue());
this->Layout();
});
m_fine_radioBox->Bind(wxEVT_RADIOBUTTON, [this, flow_ratio_input](auto& e) {
flow_ratio_input->Show(m_fine_radioBox->GetValue());
this->Layout();
});
page1_content_sizer->AddSpacer(PRESET_GAP);
page1_content_sizer->Add(m_choose_step_panel, 0);
}
// Hide
m_all_pages_sizer->Add(m_page1, 1, wxEXPAND | wxALL, FromDIP(25));
// page 2 : print page
m_page2 = create_print_page();
m_page2->set_page_title(_L("Flow Rate"));
m_all_pages_sizer->Add(m_page2, 1, wxEXPAND | wxALL, FromDIP(25));
m_page0->chain(m_page1)->chain(m_page2);
m_first_page = m_page0;
m_curr_page = m_page0;
show_page(m_curr_page);
create_low_end_pages();
}
void FlowRateWizard::request_calib_result() {
// todo emit once and loop to get
CalibUtils::emit_get_flow_ratio_calib_results();
CalibUtils::get_flow_ratio_calib_results(m_calib_results);
// todo if get result failed
sync_save_page_data();
}
void FlowRateWizard::sync_save_page_data() {
FilamentComboBoxList fcb_list = get_selected_filament_comboBox();
m_grid_panel->DestroyChildren();
wxBoxSizer* grid_sizer = new wxBoxSizer(wxHORIZONTAL);
const int COLUMN_GAP = FromDIP(50);
const int ROW_GAP = FromDIP(30);
wxBoxSizer* left_title_sizer = new wxBoxSizer(wxVERTICAL);
left_title_sizer->AddSpacer(FromDIP(49));
auto flow_ratio_title = new wxStaticText(m_grid_panel, wxID_ANY, _L("Flow Ratio"), wxDefaultPosition, wxDefaultSize, 0);
flow_ratio_title->SetFont(Label::Head_14);
left_title_sizer->Add(flow_ratio_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto brand_title = new wxStaticText(m_grid_panel, wxID_ANY, _L("Brand Name"), wxDefaultPosition, wxDefaultSize, 0);
brand_title->SetFont(Label::Head_14);
left_title_sizer->Add(brand_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
grid_sizer->Add(left_title_sizer);
grid_sizer->AddSpacer(COLUMN_GAP);
int i = 0;
for (auto fcb : fcb_list) {
wxBoxSizer* column_data_sizer = new wxBoxSizer(wxVERTICAL);
auto tray_title = new wxStaticText(m_grid_panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
tray_title->SetFont(Label::Head_14);
tray_title->SetLabel(fcb->get_tray_name());
column_data_sizer->Add(tray_title, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto flow_ratio_value = new wxStaticText(m_grid_panel, wxID_ANY, NA_STR, wxDefaultPosition, wxDefaultSize, 0);
for (auto calib_result : m_calib_results) {
if (calib_result.tray_id == fcb->get_tray_id()) {
flow_ratio_value->SetLabel(std::to_string(calib_result.flow_ratio));
}
}
column_data_sizer->Add(flow_ratio_value, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
auto comboBox_tray_name = new TextInput(m_grid_panel, fcb->GetComboBox()->GetValue(), "", "", wxDefaultPosition, CALIBRATION_FROM_TO_INPUT_SIZE);// todo use m_high_end_save_names[i] to initial
column_data_sizer->Add(comboBox_tray_name, 0, wxALIGN_CENTER | wxBOTTOM, ROW_GAP);
comboBox_tray_name->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this, comboBox_tray_name, i](auto& e) {
m_high_end_save_names[i] = comboBox_tray_name->GetTextCtrl()->GetValue().ToStdString();
});
grid_sizer->Add(column_data_sizer);
grid_sizer->AddSpacer(COLUMN_GAP);
i++;
}
m_grid_panel->SetSizer(grid_sizer, true);
Layout();
}
void FlowRateWizard::switch_pages(SimpleEvent& evt) {
if (curr_obj) {
if (is_high_end_type(curr_obj)) {
m_choose_step_panel->Hide();
}
else {
m_choose_step_panel->Show();
}
if (is_high_end_type(curr_obj))
{
if (m_low_end_page3) {
m_low_end_page3->Destroy();
m_low_end_page3 = nullptr;
}
if (m_low_end_page4) {
m_low_end_page4->Destroy();
m_low_end_page4 = nullptr;
}
if (m_low_end_page5) {
m_low_end_page5->Destroy();
m_low_end_page5 = nullptr;
}
if (m_high_end_page3)
m_high_end_page3->Destroy();
create_high_end_pages();
sync_save_page_data(); // CALIBRATION_DEBUG
}
else
{
if (m_high_end_page3) {
m_high_end_page3->Destroy();
m_high_end_page3 = nullptr;
}
if (m_low_end_page3)
m_low_end_page3->Destroy();
create_low_end_pages();
}
Layout();
}
}
void FlowRateWizard::change_ams_select_mode() {
if (is_high_end_type(curr_obj)) {
set_ams_select_mode(FSMCheckBoxMode);
}
else {
set_ams_select_mode(FSMRadioMode);
}
}
bool FlowRateWizard::start_calibration(std::vector<int> tray_ids)
{
int nozzle_temp = -1;
int bed_temp = -1;
float max_volumetric_speed = -1;
nozzle_temp = stoi(m_nozzle_temp->GetTextCtrl()->GetValue().ToStdString());
bed_temp = stoi(m_bed_temp->GetTextCtrl()->GetValue().ToStdString());
max_volumetric_speed = stof(m_max_volumetric_speed->GetTextCtrl()->GetValue().ToStdString());
if (bed_temp < 0 || nozzle_temp < 0 || max_volumetric_speed < 0) {
MessageDialog msg_dlg(nullptr, _L("Make sure bed_temp > 0 \nnozzle_temp > 0\nmax_volumetric_speed > 0"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
if (is_high_end_type(curr_obj)) {
m_calib_results.clear();
X1CCalibInfos calib_infos;
for (int tray_id : tray_ids) {
X1CCalibInfos::X1CCalibInfo calib_info;
calib_info.tray_id = tray_id;
calib_info.nozzle_diameter = dynamic_cast<ConfigOptionFloats *>(m_printer_preset->config.option("nozzle_diameter"))->get_at(0);
calib_info.filament_id = m_filament_preset->filament_id;
calib_info.setting_id = m_filament_preset->setting_id;
calib_info.bed_temp = bed_temp;
calib_info.nozzle_temp = nozzle_temp;
calib_info.max_volumetric_speed = max_volumetric_speed;
calib_infos.calib_datas.push_back(calib_info);
}
std::string error_message;
CalibUtils::calib_flowrate_X1C(calib_infos, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, error_message, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_page(get_curr_page()->get_next_page());
save_to_printer_calib_info(PageType::Calibration);
return true;
}
else {
int pass = -1;
if (m_fine_radioBox->GetValue()) {
m_curr_page = m_low_end_page3;
reset_print_panel_to_page(m_low_end_page4, m_low_end_page4->get_content_vsizer());
}
if (get_curr_page() == m_page1) {
pass = 1;
}
else if (get_curr_page() == m_low_end_page3)
pass = 2;
else
return false;
CalibInfo calib_info;
calib_info.dev_id = curr_obj->dev_id;
calib_info.select_ams = "[" + std::to_string(tray_ids[0]) + "]";
calib_info.process_bar = m_send_progress_bar;
calib_info.bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
calib_info.printer_prest = m_printer_preset;
calib_info.filament_prest = m_filament_preset;
calib_info.print_prest = m_print_preset;
std::string error_message;
CalibUtils::calib_flowrate(pass, calib_info, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, error_message, wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_send_progress_bar(true);
if (pass == 1)
save_to_printer_calib_info(PageType::Calibration);
else if(pass == 2)
save_to_printer_calib_info(PageType::FineCalibration);
return true;
}
}
bool FlowRateWizard::save_calibration_result()
{
if (is_high_end_type(curr_obj)) {
DynamicPrintConfig& filament_config = m_filament_preset->config;
for (int i = 0; i < m_calib_results.size(); i++) {
// todo failed to get result logic
//if (!calib_result.flow_ratio)
//{
// MessageDialog msg_dlg(nullptr, _L("Failed to get result, input a value manually."), wxEmptyString, wxICON_WARNING | wxOK);
// msg_dlg.ShowModal();
// return false;
//}
// todo if names are same, will be covered, need to initialize names
if (m_high_end_save_names[i].empty()) {
MessageDialog msg_dlg(nullptr, _L("Input name of filament preset to save"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
save_presets("filament_flow_ratio", new ConfigOptionFloats{ m_calib_results[i].flow_ratio }, m_high_end_save_names[i]);
}
m_calib_results.clear();
m_calib_results.shrink_to_fit();
MessageDialog msg_dlg(nullptr, _L("Saved success."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return true;
}
else {
bool valid = true;
float result_value;
if (m_checkBox_skip_calibration->GetValue()) {
result_value = m_coarse_calc_result;
if (m_optimal_block_coarse->GetValue().IsEmpty())
valid = false;
}
else {
result_value = m_fine_calc_result;
if (m_optimal_block_coarse->GetValue().IsEmpty() || m_optimal_block_fine->GetValue().IsEmpty())
valid = false;
}
if (!valid)
{
MessageDialog msg_dlg(nullptr, _L("Choose a block with smoothest top surface."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
if (m_save_name.empty()) {
MessageDialog msg_dlg(nullptr, _L("Input name of filament preset to save"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
DynamicPrintConfig& filament_config = m_filament_preset->config;
save_presets("filament_flow_ratio", new ConfigOptionFloats{ result_value }, m_save_name);
reset_send_progress_to_page(m_page1, m_page1->get_btn_hsizer());
reset_print_panel_to_page(m_page2, m_page2->get_content_vsizer()); // todo if fine calibration breakdown, should reset too.
MessageDialog msg_dlg(nullptr, _L("Saved success."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return true;
}
return false;
}
bool FlowRateWizard::recommend_input_value()
{
return CalibrationWizard::recommend_input_value();
}
void FlowRateWizard::reset_print_panel_to_page(CalibrationWizardPage* page, wxBoxSizer* sizer)
{
m_btn_next = page->get_next_btn();
m_print_panel->Reparent(page);
sizer->Add(m_print_panel, 0, wxALIGN_CENTER, 0);
}
void FlowRateWizard::reset_send_progress_to_page(CalibrationWizardPage* page, wxBoxSizer* sizer)
{
m_send_progress_panel->Reparent(page);
}
void FlowRateWizard::on_fine_tune(wxCommandEvent& e) {
if (m_optimal_block_coarse->GetValue().IsEmpty()){
MessageDialog msg_dlg(nullptr, _L("Choose a block with smoothest top surface."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return;
}
DynamicPrintConfig& filament_config = m_filament_preset->config;
filament_config.set_key_value("filament_flow_ratio", new ConfigOptionFloats{ m_coarse_calc_result });
reset_send_progress_to_page(m_low_end_page3, m_low_end_page3->get_btn_hsizer());
reset_print_panel_to_page(m_low_end_page4, m_low_end_page4->get_content_vsizer());
save_to_printer_calib_info(PageType::Save);
e.Skip();
}
void FlowRateWizard::init_bitmaps()
{
m_print_picture->SetBitmap(create_scaled_bitmap("flow_rate_calibration", nullptr, 400));
m_low_record_picture1->SetMinSize(wxSize(560, 450));
m_low_record_picture1->SetBackgroundColour(*wxBLACK);
m_low_print_picture2->SetBitmap(create_scaled_bitmap("flow_rate_calibration_fine", nullptr, 400));
m_low_record_picture2->SetMinSize(wxSize(560, 450));
m_low_record_picture2->SetBackgroundColour(*wxBLACK);
}
MaxVolumetricSpeedWizard::MaxVolumetricSpeedWizard(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: CalibrationWizard(parent, CalibMode::Calib_Vol_speed_Tower, id, pos, size, style)
{
create_pages();
init_bitmaps();
m_optimal_max_speed->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_optimal_max_speed->GetTextCtrl()->GetValue().IsEmpty()) {
m_calc_result = stof(m_optimal_max_speed->GetTextCtrl()->GetValue().ToStdString()); // todo determine to select an object or input target value directly
m_calc_result_text->SetLabel(wxString::Format(_L("max volumetric speed : %s "), std::to_string(m_calc_result)));
}
});
}
void MaxVolumetricSpeedWizard::set_save_name() {
if (m_filament_preset) {
m_save_name = m_filament_preset->alias + "-Calibrated";
}
else { m_save_name = ""; }
m_save_name_input->GetTextCtrl()->SetValue(m_save_name);
}
CalibrationWizardPage* MaxVolumetricSpeedWizard::create_start_page()
{
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Start);
page->set_highlight_step_text(PageType::Start);
auto page_content_sizer = page->get_content_vsizer();
auto when_title = new wxStaticText(page, wxID_ANY, _L("When you need Max Volumetric Speed Calibration"));
when_title->SetFont(Label::Head_14);
when_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_title);
auto when_text = new wxStaticText(page, wxID_ANY, _L("Under-extrusion"));
when_text->SetFont(Label::Body_14);
when_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text);
page_content_sizer->AddSpacer(PRESET_GAP);
auto explain_title = new wxStaticText(page, wxID_ANY, _L("What will happen if the Max Volumetric Speed is not set up properly"));
explain_title->SetFont(Label::Head_14);
explain_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(explain_title);
auto explain_text1 = new wxStaticText(page, wxID_ANY, _L("Under-extrusion: If the value is set too high, under-extrusion will happen and cause poor apperance on the printed model"));
explain_text1->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
explain_text1->SetFont(Label::Body_14);
page_content_sizer->Add(explain_text1);
auto explain_text2 = new wxStaticText(page, wxID_ANY, _L("Print speed is limited: If the value is set too low, the print speed will be limited and make the print time longer. Take the model on the right picture for example. max volumetric speed [n] mm^3/s costs [x] minutes. max volumetric speed [m] mm^3/s costs [y] minutes"));
explain_text2->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
explain_text2->SetFont(Label::Body_14);
page_content_sizer->Add(explain_text2);
page_content_sizer->AddSpacer(PRESET_GAP);
auto bitmap_sizer = new wxBoxSizer(wxHORIZONTAL);
auto bitmap1 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap1->SetMinSize(wxSize(560, 450));
bitmap1->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap1, 0, wxALL, 0);
bitmap_sizer->AddSpacer(FromDIP(20));
auto bitmap2 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap2->SetMinSize(wxSize(560, 450));
bitmap2->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap2, 0, wxALL, 0);
page_content_sizer->Add(bitmap_sizer, 0, wxALL, 0);
page_content_sizer->AddSpacer(PRESET_GAP);
auto wiki = new wxStaticText(page, wxID_ANY, _L("Wiki"));
wiki->SetFont(Label::Head_14);
wiki->SetForegroundColour({ 0, 88, 220 });
wiki->Bind(wxEVT_ENTER_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_HAND);
});
wiki->Bind(wxEVT_LEAVE_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_ARROW);
});
wiki->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty()) wxLaunchDefaultBrowser(m_wiki_url);
});
page_content_sizer->Add(wiki, 0);
page->get_prev_btn()->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Start"));
page_next_btn->SetButtonType(ButtonType::Start);
return page;
}
void MaxVolumetricSpeedWizard::create_save_panel_content(wxBoxSizer* sizer)
{
auto complete_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Please find the best object on your plate"), wxDefaultPosition, wxDefaultSize, 0);
complete_text->SetFont(::Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
sizer->Add(complete_text, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
m_record_picture = new wxStaticBitmap(m_save_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
sizer->Add(m_record_picture, 0, wxALIGN_CENTER, 0);
sizer->AddSpacer(FromDIP(20));
auto value_sizer = new wxBoxSizer(wxVERTICAL);
auto value_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Input Value"), wxDefaultPosition, wxDefaultSize, 0);
value_text->SetFont(Label::Head_14);
value_text->Wrap(-1);
m_optimal_max_speed = new TextInput(m_save_panel, wxEmptyString, "", "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, wxTE_PROCESS_ENTER);
m_optimal_max_speed->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
m_calc_result_text = new wxStaticText(m_save_panel, wxID_ANY, "");
value_sizer->Add(value_text, 0, 0, 0);
value_sizer->Add(m_optimal_max_speed, 0);
value_sizer->Add(m_calc_result_text, 0);
sizer->Add(value_sizer, 0, 0);
sizer->AddSpacer(FromDIP(20));
auto save_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Save to Filament Preset"), wxDefaultPosition, wxDefaultSize, 0);
save_text->Wrap(-1);
save_text->SetFont(Label::Head_14);
sizer->Add(save_text, 0, 0, 0);
m_save_name_input = new TextInput(m_save_panel, m_save_name, "", "", wxDefaultPosition, { CALIBRATION_TEXT_MAX_LENGTH, FromDIP(24) }, 0);
sizer->Add(m_save_name_input, 0, 0, 0);
m_save_name_input->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_save_name_input->GetTextCtrl()->GetValue().IsEmpty())
m_save_name = m_save_name_input->GetTextCtrl()->GetValue().ToStdString();
else
m_save_name = "";
});
}
void MaxVolumetricSpeedWizard::create_pages()
{
// page 0 : start page
m_page0 = create_start_page();
m_page0->set_page_title(_L("Max Volumetric Speed"));
m_all_pages_sizer->Add(m_page0, 1, wxEXPAND | wxALL, FromDIP(25));
// page 1 : preset page
m_page1 = create_presets_page(true);
m_page1->set_page_title(_L("Max Volumetric Speed"));
m_from_text->SetLabel(_L("From Volumetric Speed"));
m_to_text->SetLabel(_L("To Volumetric Speed"));
m_from_value->SetLabel(_L("mm\u00B3/s"));
m_to_value->SetLabel(_L("mm\u00B3/s"));
m_step->SetLabel(_L("mm\u00B3/s"));
m_step->GetTextCtrl()->SetLabel(_L("0.5"));
m_all_pages_sizer->Add(m_page1, 1, wxEXPAND | wxALL, FromDIP(25));
// page 2 : print page
m_page2 = create_print_page();
m_page2->set_page_title(_L("Max Volumetric Speed"));
m_all_pages_sizer->Add(m_page2, 1, wxEXPAND | wxALL, FromDIP(25));
// page 3 : save page
m_page3 = create_save_page();
m_page3->set_page_title(_L("Max Volumetric Speed"));
m_all_pages_sizer->Add(m_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// link page
m_page0->chain(m_page1)->chain(m_page2)->chain(m_page3);
m_first_page = m_page0;
m_curr_page = m_page0;
show_page(m_curr_page);
}
bool MaxVolumetricSpeedWizard::start_calibration(std::vector<int> tray_ids)
{
Calib_Params params;
m_from_value->GetTextCtrl()->GetValue().ToDouble(&params.start);
m_to_value->GetTextCtrl()->GetValue().ToDouble(&params.end);
m_step->GetTextCtrl()->GetValue().ToDouble(&params.step);
params.mode = CalibMode::Calib_Vol_speed_Tower;
if (params.start <= 0 || params.step <= 0 || params.end < (params.start + params.step) || params.end > 60) {
MessageDialog msg_dlg(nullptr, _L("Please input valid values:\nFrom > 0\nTo < 60\nStep >= 0\nTo > From + Step"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
CalibInfo calib_info;
calib_info.params = params;
calib_info.dev_id = curr_obj->dev_id;
calib_info.select_ams = "[" + std::to_string(tray_ids[0]) + "]";
calib_info.process_bar = m_send_progress_bar;
calib_info.bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
calib_info.printer_prest = m_printer_preset;
calib_info.filament_prest = m_filament_preset;
calib_info.print_prest = m_print_preset;
std::string error_message;
CalibUtils::calib_max_vol_speed(calib_info, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, _L(error_message), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_send_progress_bar(true);
return true;
}
bool MaxVolumetricSpeedWizard::save_calibration_result()
{
if (m_optimal_max_speed->GetTextCtrl()->GetValue().IsEmpty())
{
MessageDialog msg_dlg(nullptr, _L("Input a value."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
double max_volumetric_speed;
m_optimal_max_speed->GetTextCtrl()->GetValue().ToDouble(&max_volumetric_speed);
if (m_save_name.empty()) {
MessageDialog msg_dlg(nullptr, _L("Input name of filament preset to save"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
save_presets("filament_max_volumetric_speed", new ConfigOptionFloats{ max_volumetric_speed }, m_save_name);
return true;
}
bool MaxVolumetricSpeedWizard::recommend_input_value()
{
if (!CalibrationWizard::recommend_input_value()) {
m_from_value->GetTextCtrl()->SetValue(wxEmptyString);
m_to_value->GetTextCtrl()->SetValue(wxEmptyString);
return false;
}
else {
m_from_value->GetTextCtrl()->SetValue("5");
m_to_value->GetTextCtrl()->SetValue("20");
return true;
}
}
void MaxVolumetricSpeedWizard::init_bitmaps()
{
m_print_picture->SetBitmap(create_scaled_bitmap("max_volumetric_speed_calibration", nullptr, 400));
m_record_picture->SetMinSize(wxSize(500, 400));
m_record_picture->SetBackgroundColour(*wxBLACK);
}
TemperatureWizard::TemperatureWizard(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: CalibrationWizard(parent, CalibMode::Calib_Temp_Tower, id, pos, size, style)
{
create_pages();
init_bitmaps();
}
void TemperatureWizard::set_save_name() {
if (m_filament_preset) {
m_save_name = m_filament_preset->alias + "-Calibrated";
}
else { m_save_name = ""; }
m_save_name_input->GetTextCtrl()->SetValue(m_save_name);
}
CalibrationWizardPage* TemperatureWizard::create_start_page()
{
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Start);
page->set_highlight_step_text(PageType::Start);
auto page_content_sizer = page->get_content_vsizer();
auto when_title = new wxStaticText(page, wxID_ANY, _L("When you need Temperature Calibration"));
when_title->SetFont(Label::Head_14);
when_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_title);
auto when_text1 = new wxStaticText(page, wxID_ANY, _L("Model stringing"));
when_text1->SetFont(Label::Body_14);
when_text1->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text1);
auto when_text2 = new wxStaticText(page, wxID_ANY, _L("Layer adhesion problem"));
when_text2->SetFont(Label::Body_14);
when_text2->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text2);
auto when_text3 = new wxStaticText(page, wxID_ANY, _L("Warping(overhang)"));
when_text3->SetFont(Label::Body_14);
when_text3->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text3);
auto when_text4 = new wxStaticText(page, wxID_ANY, _L("Bridging"));
when_text4->SetFont(Label::Body_14);
when_text4->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text4);
page_content_sizer->AddSpacer(PRESET_GAP);
auto bitmap_sizer = new wxBoxSizer(wxHORIZONTAL);
auto bitmap1 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap1->SetMinSize(wxSize(560, 450));
bitmap1->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap1, 0, wxALL, 0);
bitmap_sizer->AddSpacer(FromDIP(20));
auto bitmap2 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap2->SetMinSize(wxSize(560, 450));
bitmap2->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap2, 0, wxALL, 0);
page_content_sizer->Add(bitmap_sizer, 0, wxALL, 0);
page_content_sizer->AddSpacer(PRESET_GAP);
auto wiki = new wxStaticText(page, wxID_ANY, _L("Wiki"));
wiki->SetFont(Label::Head_14);
wiki->SetForegroundColour({ 0, 88, 220 });
wiki->Bind(wxEVT_ENTER_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_HAND);
});
wiki->Bind(wxEVT_LEAVE_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_ARROW);
});
wiki->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty()) wxLaunchDefaultBrowser(m_wiki_url);
});
page_content_sizer->Add(wiki, 0);
page->get_prev_btn()->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Start"));
page_next_btn->SetButtonType(ButtonType::Start);
return page;
}
void TemperatureWizard::create_save_panel_content(wxBoxSizer* sizer)
{
auto complete_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Please find the best object on your plate"), wxDefaultPosition, wxDefaultSize, 0);
complete_text->SetFont(::Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
sizer->Add(complete_text, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
m_record_picture = new wxStaticBitmap(m_save_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
sizer->Add(m_record_picture, 0, wxALIGN_CENTER, 0);
sizer->AddSpacer(FromDIP(20));
auto optimal_temp_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Optimal Temp"), wxDefaultPosition, wxDefaultSize, 0);
optimal_temp_text->Wrap(-1);
optimal_temp_text->SetFont(Label::Head_14);
sizer->Add(optimal_temp_text, 0, 0, 0);
m_optimal_temp = new TextInput(m_save_panel, wxEmptyString, _L("\u2103"), "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0);
m_optimal_temp->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
sizer->Add(m_optimal_temp, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
auto save_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Save to Filament Preset"), wxDefaultPosition, wxDefaultSize, 0);
save_text->Wrap(-1);
save_text->SetFont(Label::Head_14);
sizer->Add(save_text, 0, 0, 0);
m_save_name_input = new TextInput(m_save_panel, m_save_name, "", "", wxDefaultPosition, { CALIBRATION_TEXT_MAX_LENGTH, FromDIP(24) }, 0);
sizer->Add(m_save_name_input, 0, 0, 0);
m_save_name_input->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_save_name_input->GetTextCtrl()->GetValue().IsEmpty())
m_save_name = m_save_name_input->GetTextCtrl()->GetValue().ToStdString();
else
m_save_name = "";
});
}
void TemperatureWizard::create_pages()
{
// page 0 : start page
m_page0 = create_start_page();
m_page0->set_page_title(_L("Temperature Calibration"));
m_all_pages_sizer->Add(m_page0, 1, wxEXPAND | wxALL, FromDIP(25));
// page 1 : preset page
m_page1 = create_presets_page(true);
m_page1->set_page_title(_L("Temperature Calibration"));
m_from_text->SetLabel(_L("From Temp"));
m_to_text->SetLabel(_L("To Temp"));
m_step->Enable(false);
m_all_pages_sizer->Add(m_page1, 1, wxEXPAND | wxALL, FromDIP(25));
// page 2 : print page
m_page2 = create_print_page();
m_page2->set_page_title(_L("Temperature Calibration"));
m_all_pages_sizer->Add(m_page2, 1, wxEXPAND | wxALL, FromDIP(25));
// page 3 : save page
m_page3 = create_save_page();
m_page3->set_page_title(_L("Temperature Calibration"));
m_all_pages_sizer->Add(m_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// link pages
m_page0->chain(m_page1)->chain(m_page2)->chain(m_page3);
m_first_page = m_page0;
m_curr_page = m_page0;
show_page(m_curr_page);
}
bool TemperatureWizard::start_calibration(std::vector<int> tray_ids)
{
Calib_Params params;
m_from_value->GetTextCtrl()->GetValue().ToDouble(&params.start);
m_to_value->GetTextCtrl()->GetValue().ToDouble(&params.end);
params.mode = CalibMode::Calib_Temp_Tower;
if (params.start < 180 || params.end > 350 || params.end < (params.start + 5) || (params.end - params.start) >= 120) { // todo
MessageDialog msg_dlg(nullptr, _L("Please input valid values:\nFrom temp: >= 180\nTo temp: <= 350\nFrom temp <= To temp - Step\n From temp - To temp < 120"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
CalibInfo calib_info;
calib_info.params = params;
calib_info.dev_id = curr_obj->dev_id;
calib_info.select_ams = "[" + std::to_string(tray_ids[0]) + "]";
calib_info.process_bar = m_send_progress_bar;
calib_info.bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
calib_info.printer_prest = m_printer_preset;
calib_info.filament_prest = m_filament_preset;
calib_info.print_prest = m_print_preset;
std::string error_message;
CalibUtils::calib_temptue(calib_info, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, _L(error_message), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_send_progress_bar(true);
return true;
}
bool TemperatureWizard::save_calibration_result()
{
if (m_optimal_temp->GetTextCtrl()->GetValue().IsEmpty()) // todo need a valid range
{
MessageDialog msg_dlg(nullptr, _L("Input an optiaml temperature."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
int temp = stoi(m_optimal_temp->GetTextCtrl()->GetValue().ToStdString());
if (m_save_name.empty()) {
MessageDialog msg_dlg(nullptr, _L("Input name of filament preset to save"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
save_presets("nozzle_temperature", new ConfigOptionInts(1, temp), m_save_name);
return true;
}
bool TemperatureWizard::recommend_input_value()
{
if (!CalibrationWizard::recommend_input_value()) {
m_from_value->GetTextCtrl()->SetValue(wxEmptyString);
m_to_value->GetTextCtrl()->SetValue(wxEmptyString);
return false;
}
else {
wxString filament_name = m_filament_preset->alias;
int start, end;
if (filament_name.Contains("ABS") || filament_name.Contains("ASA")) {//todo supplement
start = 230;
end = 270;
}
else if (filament_name.Contains("PETG")) {
start = 230;
end = 260;
}
else if (filament_name.Contains("TPU")) {
start = 210;
end = 240;
}
else if (filament_name.Contains("PA-CF")) {
start = 280;
end = 320;
}
else if (filament_name.Contains("PET-CF")) {
start = 280;
end = 320;
}
else if (filament_name.Contains("PLA")) {
start = 190;
end = 230;
}
else {
start = 190;
end = 230;
}
m_from_value->GetTextCtrl()->SetValue(std::to_string(start));
m_to_value->GetTextCtrl()->SetValue(std::to_string(end));
return true;
}
}
void TemperatureWizard::init_bitmaps()
{
m_print_picture->SetBitmap(create_scaled_bitmap("temperature_calibration", nullptr, 400));
m_record_picture->SetBitmap(create_scaled_bitmap("temperature_record", nullptr, 400));
}
RetractionWizard::RetractionWizard(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: CalibrationWizard(parent, CalibMode::Calib_Retraction_tower, id, pos, size, style)
{
create_pages();
init_bitmaps();
}
void RetractionWizard::set_save_name() {
if (m_filament_preset) {
m_save_name = m_filament_preset->alias + "-Calibrated";
}
else { m_save_name = ""; }
m_save_name_input->GetTextCtrl()->SetValue(m_save_name);
}
void RetractionWizard::create_save_panel_content(wxBoxSizer* sizer)
{
auto complete_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Please find the best object on your plate"), wxDefaultPosition, wxDefaultSize, 0);
complete_text->SetFont(::Label::Head_14);
complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
sizer->Add(complete_text, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
m_record_picture = new wxStaticBitmap(m_save_panel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
sizer->Add(m_record_picture, 0, wxALIGN_CENTER, 0);
sizer->AddSpacer(FromDIP(20));
auto optimal_temp_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Optimal Retraction Length"), wxDefaultPosition, wxDefaultSize, 0);
optimal_temp_text->Wrap(-1);
optimal_temp_text->SetFont(Label::Head_14);
sizer->Add(optimal_temp_text, 0, 0, 0);
m_optimal_retraction = new TextInput(m_save_panel, wxEmptyString, _L("mm"), "", wxDefaultPosition, CALIBRATION_OPTIMAL_INPUT_SIZE, 0);
m_optimal_retraction->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC));
sizer->Add(m_optimal_retraction, 0, 0, 0);
sizer->AddSpacer(FromDIP(20));
auto save_text = new wxStaticText(m_save_panel, wxID_ANY, _L("Save to Filament Preset"), wxDefaultPosition, wxDefaultSize, 0);
save_text->Wrap(-1);
save_text->SetFont(Label::Head_14);
sizer->Add(save_text, 0, 0, 0);
m_save_name_input = new TextInput(m_save_panel, m_save_name, "", "", wxDefaultPosition, { CALIBRATION_TEXT_MAX_LENGTH, FromDIP(24) }, 0);
sizer->Add(m_save_name_input, 0, 0, 0);
m_save_name_input->GetTextCtrl()->Bind(wxEVT_TEXT, [this](auto& e) {
if (!m_save_name_input->GetTextCtrl()->GetValue().IsEmpty())
m_save_name = m_save_name_input->GetTextCtrl()->GetValue().ToStdString();
else
m_save_name = "";
});
}
CalibrationWizardPage* RetractionWizard::create_start_page()
{
auto page = new CalibrationWizardPage(m_scrolledWindow);
page->set_page_type(PageType::Start);
page->set_highlight_step_text(PageType::Start);
auto page_content_sizer = page->get_content_vsizer();
auto when_title = new wxStaticText(page, wxID_ANY, _L("When you need Temperature Calibration"));
when_title->SetFont(Label::Head_14);
when_title->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_title);
auto when_text1 = new wxStaticText(page, wxID_ANY, _L("Model stringing"));
when_text1->SetFont(Label::Body_14);
when_text1->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text1);
auto when_text2 = new wxStaticText(page, wxID_ANY, _L("Layer adhesion problem"));
when_text2->SetFont(Label::Body_14);
when_text2->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text2);
auto when_text3 = new wxStaticText(page, wxID_ANY, _L("Warping(overhang)"));
when_text3->SetFont(Label::Body_14);
when_text3->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text3);
auto when_text4 = new wxStaticText(page, wxID_ANY, _L("Bridging"));
when_text4->SetFont(Label::Body_14);
when_text4->Wrap(CALIBRATION_TEXT_MAX_LENGTH);
page_content_sizer->Add(when_text4);
auto bitmap_sizer = new wxBoxSizer(wxHORIZONTAL);
auto bitmap1 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap1->SetMinSize(wxSize(560, 450));
bitmap1->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap1, 0, wxALL, 0);
bitmap_sizer->AddSpacer(FromDIP(20));
auto bitmap2 = new wxStaticBitmap(page, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0);
bitmap2->SetMinSize(wxSize(560, 450));
bitmap2->SetBackgroundColour(*wxBLACK);
bitmap_sizer->Add(bitmap2, 0, wxALL, 0);
page_content_sizer->Add(bitmap_sizer, 0, wxALL, 0);
page_content_sizer->AddSpacer(PRESET_GAP);
auto wiki = new wxStaticText(page, wxID_ANY, _L("Wiki"));
wiki->SetFont(Label::Head_14);
wiki->SetForegroundColour({ 0, 88, 220 });
wiki->Bind(wxEVT_ENTER_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_HAND);
});
wiki->Bind(wxEVT_LEAVE_WINDOW, [this, wiki](wxMouseEvent& e) {
e.Skip();
SetCursor(wxCURSOR_ARROW);
});
wiki->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& e) {
if (!m_wiki_url.empty()) wxLaunchDefaultBrowser(m_wiki_url);
});
page_content_sizer->Add(wiki, 0);
page->get_prev_btn()->Hide();
auto page_next_btn = page->get_next_btn();
page_next_btn->SetLabel(_L("Start"));
page_next_btn->SetButtonType(ButtonType::Start);
return page;
}
void RetractionWizard::create_pages()
{
// page 1 : preset page
m_page1 = create_presets_page(true);
m_page1->set_page_title(_L("Retraction Calibration"));
m_from_text->SetLabel(_L("From Retraction Length"));
m_to_text->SetLabel(_L("To Retraction Length"));
m_from_value->SetLabel(_L("mm"));
m_to_value->SetLabel(_L("mm"));
m_step->SetLabel(_L("mm"));
m_step->GetTextCtrl()->SetLabel(_L("0.1"));
m_all_pages_sizer->Add(m_page1, 1, wxEXPAND | wxALL, FromDIP(25));
// page 2 : print page
m_page2 = create_print_page();
m_page2->set_page_title(_L("Retraction Calibration"));
m_all_pages_sizer->Add(m_page2, 1, wxEXPAND | wxALL, FromDIP(25));
// page 3 : save page
m_page3 = create_save_page();
m_page3->set_page_title(_L("Retraction Calibration"));
m_all_pages_sizer->Add(m_page3, 1, wxEXPAND | wxALL, FromDIP(25));
// link pages
m_page1->chain(m_page2)->chain(m_page3);
m_first_page = m_page1;
m_curr_page = m_page1;
show_page(m_curr_page);
}
bool RetractionWizard::start_calibration(std::vector<int> tray_ids)
{
Calib_Params params;
m_from_value->GetTextCtrl()->GetValue().ToDouble(&params.start);
m_to_value->GetTextCtrl()->GetValue().ToDouble(&params.end);
params.mode = CalibMode::Calib_Temp_Tower;
// todo limit
//if (params.start < 180 || params.end > 350 || params.end < (params.start + 5) || (params.end - params.start) >= 120) { // todo
// MessageDialog msg_dlg(nullptr, _L("Please input valid values:\nFrom temp: >= 180\nTo temp: <= 350\nFrom temp <= To temp - Step\n From temp - To temp < 120"), wxEmptyString, wxICON_WARNING | wxOK);
// msg_dlg.ShowModal();
// return false;
//}
CalibInfo calib_info;
calib_info.params = params;
calib_info.dev_id = curr_obj->dev_id;
calib_info.select_ams = "[" + std::to_string(tray_ids[0]) + "]";
calib_info.process_bar = m_send_progress_bar;
calib_info.bed_type = BedType(m_comboBox_bed_type->GetSelection() + btDefault + 1);
calib_info.printer_prest = m_printer_preset;
calib_info.filament_prest = m_filament_preset;
calib_info.print_prest = m_print_preset;
std::string error_message;
CalibUtils::calib_retraction(calib_info, error_message);
if (!error_message.empty()) {
MessageDialog msg_dlg(nullptr, _L(error_message), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
show_send_progress_bar(true);
return true;
}
bool RetractionWizard::save_calibration_result()
{
if (m_optimal_retraction->GetTextCtrl()->GetValue().IsEmpty()) // todo need a valid range
{
MessageDialog msg_dlg(nullptr, _L("Input an optiaml retraction length."), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
float length = stof(m_optimal_retraction->GetTextCtrl()->GetValue().ToStdString());
if (m_save_name.empty()) {
MessageDialog msg_dlg(nullptr, _L("Input name of filament preset to save"), wxEmptyString, wxICON_WARNING | wxOK);
msg_dlg.ShowModal();
return false;
}
save_presets("retraction_length", new ConfigOptionFloats{ length }, m_save_name);
return true;
}
bool RetractionWizard::recommend_input_value()
{
if (!CalibrationWizard::recommend_input_value()) {
m_from_value->GetTextCtrl()->SetValue(wxEmptyString);
m_to_value->GetTextCtrl()->SetValue(wxEmptyString);
return false;
}
else {
m_from_value->GetTextCtrl()->SetValue("0");
m_to_value->GetTextCtrl()->SetValue("2");
return true;
}
}
void RetractionWizard::init_bitmaps()
{
m_print_picture->SetBitmap(create_scaled_bitmap("temperature_calibration", nullptr, 400));
m_record_picture->SetBitmap(create_scaled_bitmap("temperature_record", nullptr, 400));
}
}}