diff --git a/resources/calib/pressure_advance/pa_pattern.3mf b/resources/calib/pressure_advance/pa_pattern.3mf new file mode 100644 index 0000000000..01e3d44396 Binary files /dev/null and b/resources/calib/pressure_advance/pa_pattern.3mf differ diff --git a/resources/images/fd_pattern_manual.png b/resources/images/fd_pattern_manual.png new file mode 100644 index 0000000000..2aefb4edb1 Binary files /dev/null and b/resources/images/fd_pattern_manual.png differ diff --git a/resources/images/fd_pattern_manual_result.png b/resources/images/fd_pattern_manual_result.png new file mode 100644 index 0000000000..dfea0e00bf Binary files /dev/null and b/resources/images/fd_pattern_manual_result.png differ diff --git a/resources/images/fd_pattern_manual_result_CN.png b/resources/images/fd_pattern_manual_result_CN.png new file mode 100644 index 0000000000..255aed5f0e Binary files /dev/null and b/resources/images/fd_pattern_manual_result_CN.png differ diff --git a/src/libslic3r/Calib.cpp b/src/libslic3r/Calib.cpp index b210d36721..d52a2ca67c 100644 --- a/src/libslic3r/Calib.cpp +++ b/src/libslic3r/Calib.cpp @@ -429,6 +429,17 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(const DynamicPrintConfi model.plates_custom_gcodes[model.curr_plate_index] = info; } +void CalibPressureAdvancePattern::set_start_offset(const Vec3d &offset) +{ + m_starting_point = offset; + m_is_start_point_fixed = true; +} + +Vec3d CalibPressureAdvancePattern::get_start_offset() +{ + return m_starting_point; +} + void CalibPressureAdvancePattern::refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin) { m_config = config; @@ -443,6 +454,9 @@ void CalibPressureAdvancePattern::refresh_setup(const DynamicPrintConfig &config void CalibPressureAdvancePattern::_refresh_starting_point(const Model &model) { + if (m_is_start_point_fixed) + return; + ModelObject * obj = model.objects.front(); BoundingBoxf3 bbox = obj->instance_bounding_box(*obj->instances.front(), false); diff --git a/src/libslic3r/Calib.hpp b/src/libslic3r/Calib.hpp index 9311f244a2..4077bad9c7 100644 --- a/src/libslic3r/Calib.hpp +++ b/src/libslic3r/Calib.hpp @@ -219,6 +219,9 @@ public: void generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin); + void set_start_offset(const Vec3d &offset); + Vec3d get_start_offset(); + protected: double speed_first_layer() const { return m_config.option("initial_layer_speed")->value; }; double speed_perimeter() const { return m_config.option("outer_wall_speed")->value; }; @@ -290,6 +293,7 @@ private: GCodeWriter m_writer; bool m_is_delta; Vec3d m_starting_point; + bool m_is_start_point_fixed = false; const double m_handle_xy_size{5}; const double m_handle_spacing{2}; diff --git a/src/slic3r/GUI/CalibrationWizard.cpp b/src/slic3r/GUI/CalibrationWizard.cpp index 3171e4b471..ebb55ee158 100644 --- a/src/slic3r/GUI/CalibrationWizard.cpp +++ b/src/slic3r/GUI/CalibrationWizard.cpp @@ -15,6 +15,9 @@ wxDEFINE_EVENT(EVT_DEVICE_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_CALIBRATION_JOB_FINISHED, wxCommandEvent); static const wxString NA_STR = _L("N/A"); +static const float MIN_PA_K_VALUE = 0.0; +static const float MAX_PA_K_VALUE = 0.5; +static const float MIN_PA_K_VALUE_STEP = 0.001; bool check_preset_name_valid(const wxString& name) { wxString error_message; @@ -46,6 +49,18 @@ std::map get_cached_selected_filament(MachineObject* obj) { return selected_filament_map; } +bool is_pa_params_valid(const Calib_Params& params) +{ + if (params.start < MIN_PA_K_VALUE || params.end > MAX_PA_K_VALUE || params.step < EPSILON || params.end < params.start + params.step) { + MessageDialog msg_dlg(nullptr, + wxString::Format(_L("Please input valid values:\nStart value: >= %.1f\nEnd value: <= %.1f\nEnd value: > Start value\nValue step: >= %.3f)"), MIN_PA_K_VALUE, MAX_PA_K_VALUE, MIN_PA_K_VALUE_STEP), + wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return false; + } + return true; +} + 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) @@ -339,6 +354,18 @@ PressureAdvanceWizard::PressureAdvanceWizard(wxWindow* parent, wxWindowID id, co create_pages(); } +void PressureAdvanceWizard::on_cali_job_finished(wxString evt_data) +{ + int cali_stage = 0; + CalibMode obj_cali_mode = CalibUtils::get_calib_mode_by_name(evt_data.ToStdString(), cali_stage); + + if (obj_cali_mode == m_mode) { + show_step(cali_step); + } + // change ui, hide + static_cast(preset_step->page)->on_cali_finished_job(); +} + void PressureAdvanceWizard::create_pages() { start_step = new CalibrationWizardPageStep(new CalibrationPAStartPage(m_scrolledWindow)); @@ -422,6 +449,7 @@ void PressureAdvanceWizard::on_device_connected(MachineObject* obj) CalibrationMethod method; int cali_stage = 0; CalibMode obj_cali_mode = get_obj_calibration_mode(obj, method, cali_stage); + obj->manual_pa_cali_method = ManualPaCaliMethod(cali_stage); // show cali step when obj is in pa calibration if (obj) { @@ -431,6 +459,8 @@ void PressureAdvanceWizard::on_device_connected(MachineObject* obj) if (obj_cali_mode == m_mode) { if (!obj->cali_finished && (obj->is_in_printing() || obj->is_printing_finished())) { CalibrationWizard::set_cali_method(method); + CalibrationCaliPage *cali_page = (static_cast(cali_step->page)); + cali_page->set_pa_cali_image(cali_stage); show_step(cali_step); } } @@ -504,11 +534,13 @@ void PressureAdvanceWizard::on_cali_start() return; } - if (curr_obj->get_printer_series() == PrinterSeries::SERIES_X1) { + std::string error_message; + wxString wx_err_string; + if (m_cali_method == CalibrationMethod::CALI_METHOD_AUTO && curr_obj->get_printer_series() == PrinterSeries::SERIES_X1) { X1CCalibInfos calib_infos; - for (auto& item : selected_filaments) { - int nozzle_temp = -1; - int bed_temp = -1; + for (auto &item : selected_filaments) { + int nozzle_temp = -1; + int bed_temp = -1; float max_volumetric_speed = -1; if (!get_preset_info(item.second->config, plate_type, nozzle_temp, bed_temp, max_volumetric_speed)) { @@ -517,54 +549,92 @@ void PressureAdvanceWizard::on_cali_start() } X1CCalibInfos::X1CCalibInfo calib_info; - calib_info.tray_id = item.first; - calib_info.nozzle_diameter = nozzle_dia; - calib_info.filament_id = item.second->filament_id; - calib_info.setting_id = item.second->setting_id; - calib_info.bed_temp = bed_temp; - calib_info.nozzle_temp = nozzle_temp; + calib_info.tray_id = item.first; + calib_info.nozzle_diameter = nozzle_dia; + calib_info.filament_id = item.second->filament_id; + calib_info.setting_id = item.second->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); } + CalibUtils::calib_PA(calib_infos, 0, error_message); // mode = 0 for auto + wx_err_string = from_u8(error_message); - std::string error_message; - wxString wx_err_string; - if (m_cali_method == CalibrationMethod::CALI_METHOD_AUTO) { - CalibUtils::calib_PA(calib_infos, 0, error_message); // mode = 0 for auto - wx_err_string = from_u8(error_message); - } else if (m_cali_method == CalibrationMethod::CALI_METHOD_MANUAL) { - CalibUtils::calib_PA(calib_infos, 1, error_message); // mode = 1 for manual - wx_err_string = from_u8(error_message); - } else { - assert(false); - } if (!wx_err_string.empty()) { MessageDialog msg_dlg(nullptr, wx_err_string, wxEmptyString, wxICON_WARNING | wxOK); msg_dlg.ShowModal(); } - } - else if (curr_obj->get_printer_series() == PrinterSeries::SERIES_P1P) { + + show_step(m_curr_step->next); + } else if (m_cali_method == CalibrationMethod::CALI_METHOD_MANUAL) { if (selected_filaments.empty()) { BOOST_LOG_TRIVIAL(warning) << "CaliPreset: selected filaments is empty"; return; } + else { + int nozzle_temp = -1; + int bed_temp = -1; + float max_volumetric_speed = -1; + if (!get_preset_info(selected_filaments.begin()->second->config, plate_type, nozzle_temp, bed_temp, max_volumetric_speed)) { + BOOST_LOG_TRIVIAL(error) << "CaliPreset: get preset info error"; + return; + } + + CalibInfo calib_info; + calib_info.dev_id = curr_obj->dev_id; + calib_info.select_ams = "[" + std::to_string(selected_filaments.begin()->first) + "]"; + Preset *preset = selected_filaments.begin()->second; + Preset * temp_filament_preset = new Preset(preset->type, preset->name + "_temp"); + temp_filament_preset->config = preset->config; - int nozzle_temp = -1; - int bed_temp = -1; - float max_volumetric_speed = -1; - if (!get_preset_info(selected_filaments.begin()->second->config, plate_type, nozzle_temp, bed_temp, max_volumetric_speed)) { - BOOST_LOG_TRIVIAL(error) << "CaliPreset: get preset info error"; - return; + calib_info.bed_type = plate_type; + calib_info.process_bar = preset_page->get_sending_progress_bar(); + calib_info.printer_prest = preset_page->get_printer_preset(curr_obj, nozzle_dia); + calib_info.print_prest = preset_page->get_print_preset(); + calib_info.filament_prest = temp_filament_preset; + + wxArrayString values = preset_page->get_custom_range_values(); + if (values.size() != 3) { + MessageDialog msg_dlg(nullptr, _L("The input value size must be 3."), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } else { + values[0].ToDouble(&calib_info.params.start); + values[1].ToDouble(&calib_info.params.end); + values[2].ToDouble(&calib_info.params.step); + } + calib_info.params.mode = preset_page->get_pa_cali_method(); + + if (!is_pa_params_valid(calib_info.params)) + return; + + ManualPaCaliMethod pa_cali_method = ManualPaCaliMethod::PA_LINE; + CalibrationCaliPage *cali_page = (static_cast(cali_step->page)); + if (calib_info.params.mode == CalibMode::Calib_PA_Line) + pa_cali_method = ManualPaCaliMethod::PA_LINE; + else if (calib_info.params.mode == CalibMode::Calib_PA_Pattern) + pa_cali_method = ManualPaCaliMethod::PA_PATTERN; + + cali_page->set_pa_cali_image(int(pa_cali_method)); + curr_obj->manual_pa_cali_method = pa_cali_method; + + CalibUtils::calib_generic_PA(calib_info, error_message); + wx_err_string = from_u8(error_message); + + if (!wx_err_string.empty()) { + MessageDialog msg_dlg(nullptr, wx_err_string, wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + } + + preset_page->on_cali_start_job(); } - - curr_obj->command_start_extrusion_cali(selected_filaments.begin()->first, - nozzle_temp, bed_temp, max_volumetric_speed, setting_id); } else { assert(false); + BOOST_LOG_TRIVIAL(error) << "CaliPreset: unsupported printer type or cali method"; + return; } - show_step(m_curr_step->next); - CalibrationCaliPage* cali_page = (static_cast(cali_step->page)); cali_page->clear_last_job_status(); } diff --git a/src/slic3r/GUI/CalibrationWizard.hpp b/src/slic3r/GUI/CalibrationWizard.hpp index e5e55834ff..158d42eeaf 100644 --- a/src/slic3r/GUI/CalibrationWizard.hpp +++ b/src/slic3r/GUI/CalibrationWizard.hpp @@ -105,6 +105,9 @@ class PressureAdvanceWizard : public CalibrationWizard { public: PressureAdvanceWizard(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL); ~PressureAdvanceWizard() {}; + + void on_cali_job_finished(wxString evt_data) override; + protected: void create_pages(); diff --git a/src/slic3r/GUI/CalibrationWizardCaliPage.cpp b/src/slic3r/GUI/CalibrationWizardCaliPage.cpp index 23edc25e1d..88b3e1c7c2 100644 --- a/src/slic3r/GUI/CalibrationWizardCaliPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardCaliPage.cpp @@ -125,6 +125,17 @@ void CalibrationCaliPage::set_cali_img() } } +void CalibrationCaliPage::set_pa_cali_image(int stage) +{ + if (m_cali_mode == CalibMode::Calib_PA_Line && m_cali_method == CALI_METHOD_MANUAL) { + if (stage == 0) { + m_picture_panel->set_img(create_scaled_bitmap("fd_calibration_manual", nullptr, 400)); + } else if (stage == 1) { + m_picture_panel->set_img(create_scaled_bitmap("fd_pattern_manual", nullptr, 400)); + } + } +} + void CalibrationCaliPage::clear_last_job_status() { m_is_between_start_and_running = true; diff --git a/src/slic3r/GUI/CalibrationWizardCaliPage.hpp b/src/slic3r/GUI/CalibrationWizardCaliPage.hpp index cb608ddda4..59a07aad38 100644 --- a/src/slic3r/GUI/CalibrationWizardCaliPage.hpp +++ b/src/slic3r/GUI/CalibrationWizardCaliPage.hpp @@ -27,6 +27,7 @@ public: void update_basic_print_data(bool def, float weight = 0.0, int prediction = 0); void reset_printing_values(); void clear_last_job_status(); + void set_pa_cali_image(int stage); void on_device_connected(MachineObject* obj) override; diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index 3c1a63e9b7..eac53d08ea 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -5,6 +5,9 @@ #include "libslic3r/Print.hpp" namespace Slic3r { namespace GUI { +static wxString PA_LINE = _L("Line"); +static wxString PA_PATTERN = _L("Pattern"); + CaliPresetCaliStagePanel::CaliPresetCaliStagePanel( wxWindow* parent, wxWindowID id, @@ -124,6 +127,63 @@ void CaliPresetCaliStagePanel::set_flow_ratio_value(float flow_ratio) m_flow_ratio_value = flow_ratio; } +CaliComboBox::CaliComboBox(wxWindow* parent, + wxString title, + wxArrayString values, + int default_index, // default delected id + std::function on_value_change, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style) + : wxPanel(parent, id, pos, size, style) + , m_title(title) + , m_on_value_change_call_back(on_value_change) +{ + SetBackgroundColour(*wxWHITE); + m_top_sizer = new wxBoxSizer(wxVERTICAL); + m_top_sizer->AddSpacer(PRESET_GAP); + auto combo_title = new Label(this, title); + combo_title->SetFont(Label::Head_14); + combo_title->Wrap(-1); + m_top_sizer->Add(combo_title, 0, wxALL, 0); + m_top_sizer->AddSpacer(FromDIP(10)); + m_combo_box = new ComboBox(this, wxID_ANY, "", wxDefaultPosition, CALIBRATION_COMBOX_SIZE, 0, nullptr, wxCB_READONLY); + m_top_sizer->Add(m_combo_box, 0, wxALL, 0); + m_top_sizer->AddSpacer(PRESET_GAP); + + this->SetSizer(m_top_sizer); + m_top_sizer->Fit(this); + + // set values + for (int i = 0; i < values.size(); ++i) { + m_combo_box->AppendString(values[i]); + } + m_combo_box->SetSelection(default_index); + + // bind call back function + if (m_on_value_change_call_back) + m_combo_box->Bind(wxEVT_COMBOBOX, m_on_value_change_call_back); +} + +wxString CaliComboBox::get_value() const +{ + if (m_combo_box) + return m_combo_box->GetValue(); + + return wxString(); +} + +void CaliComboBox::set_values(const wxArrayString &values) +{ + if (m_combo_box) { + for (int i = 0; i < values.size(); ++i) { + m_combo_box->AppendString(values[i]); + } + m_combo_box->SetSelection(0); + } +} + CaliPresetWarningPanel::CaliPresetWarningPanel( wxWindow* parent, wxWindowID id, @@ -704,6 +764,13 @@ void CalibrationPresetPage::create_page(wxWindow* parent) m_filament_list_panel = new wxPanel(parent); m_filament_list_panel->SetBackgroundColour(*wxWHITE); create_filament_list_panel(m_filament_list_panel); + + if (m_cali_mode == CalibMode::Calib_PA_Line || m_cali_mode == CalibMode::Calib_PA_Pattern) { + wxArrayString pa_cali_modes; + pa_cali_modes.push_back(PA_LINE); + pa_cali_modes.push_back(PA_PATTERN); + m_pa_cali_method_combox = new CaliComboBox(parent, _L("Method"), pa_cali_modes); + } m_ext_spool_panel = new wxPanel(parent); create_ext_spool_panel(m_ext_spool_panel); @@ -719,9 +786,7 @@ void CalibrationPresetPage::create_page(wxWindow* parent) m_sending_panel->Hide(); - if (m_show_custom_range) { - m_custom_range_panel = new CaliPresetCustomRangePanel(parent); - } + m_custom_range_panel = new CaliPresetCustomRangePanel(parent); m_action_panel = new CaliPageActionPanel(parent, m_cali_mode, CaliPageType::CALI_PAGE_PRESET); @@ -732,11 +797,10 @@ void CalibrationPresetPage::create_page(wxWindow* parent) m_top_sizer->Add(m_selection_panel, 0); m_top_sizer->Add(m_filament_list_panel, 0); m_top_sizer->Add(m_ext_spool_panel, 0); + m_top_sizer->Add(m_pa_cali_method_combox, 0); + m_top_sizer->Add(m_custom_range_panel, 0); + m_top_sizer->AddSpacer(FromDIP(15)); m_top_sizer->Add(m_warning_panel, 0); - if (m_show_custom_range) { - m_top_sizer->Add(m_custom_range_panel, 0); - m_top_sizer->AddSpacer(FromDIP(15)); - } m_top_sizer->Add(m_tips_panel, 0); m_top_sizer->AddSpacer(PRESET_GAP); m_top_sizer->Add(m_sending_panel, 0, wxALIGN_CENTER); @@ -1430,16 +1494,56 @@ void CalibrationPresetPage::set_cali_filament_mode(CalibrationFilamentMode mode) void CalibrationPresetPage::set_cali_method(CalibrationMethod method) { CalibrationWizardPage::set_cali_method(method); - if (method == CalibrationMethod::CALI_METHOD_MANUAL && m_cali_mode == CalibMode::Calib_Flow_Rate) { - wxArrayString steps; - steps.Add(_L("Preset")); - steps.Add(_L("Calibration1")); - steps.Add(_L("Calibration2")); - steps.Add(_L("Record Factor")); - m_step_panel->set_steps_string(steps); - m_step_panel->set_steps(0); - if (m_cali_stage_panel) - m_cali_stage_panel->Show(); + if (method == CalibrationMethod::CALI_METHOD_MANUAL) { + if (m_cali_mode == CalibMode::Calib_Flow_Rate) { + wxArrayString steps; + steps.Add(_L("Preset")); + steps.Add(_L("Calibration1")); + steps.Add(_L("Calibration2")); + steps.Add(_L("Record Factor")); + m_step_panel->set_steps_string(steps); + m_step_panel->set_steps(0); + if (m_cali_stage_panel) + m_cali_stage_panel->Show(); + + if (m_pa_cali_method_combox) + m_pa_cali_method_combox->Show(false); + + if (m_custom_range_panel) + m_custom_range_panel->Show(false); + } + else if (m_cali_mode == CalibMode::Calib_PA_Line || m_cali_mode == CalibMode::Calib_PA_Pattern) { + if (m_cali_stage_panel) + m_cali_stage_panel->Show(false); + + if (m_pa_cali_method_combox) + m_pa_cali_method_combox->Show(); + + if (m_custom_range_panel) { + wxArrayString titles; + titles.push_back(_L("From k Value")); + titles.push_back(_L("To k Value")); + titles.push_back(_L("Step")); + m_custom_range_panel->set_titles(titles); + + wxArrayString values; + Preset* printer_preset = get_printer_preset(curr_obj, get_nozzle_value()); + int extruder_type = printer_preset->config.opt_enum("extruder_type", 0); + if (extruder_type == ExtruderType::etBowden) { + values.push_back(_L("0")); + values.push_back(_L("0.5")); + values.push_back(_L("0.05")); + } else { + values.push_back(_L("0")); + values.push_back(_L("0.05")); + values.push_back(_L("0.005")); + } + m_custom_range_panel->set_values(values); + + m_custom_range_panel->set_unit(_L("")); + m_custom_range_panel->Show(); + } + } } else { wxArrayString steps; @@ -1450,6 +1554,10 @@ void CalibrationPresetPage::set_cali_method(CalibrationMethod method) m_step_panel->set_steps(0); if (m_cali_stage_panel) m_cali_stage_panel->Show(false); + if (m_custom_range_panel) + m_custom_range_panel->Show(false); + if (m_pa_cali_method_combox) + m_pa_cali_method_combox->Show(false); } } @@ -1847,12 +1955,26 @@ std::string CalibrationPresetPage::get_print_preset_name() wxArrayString CalibrationPresetPage::get_custom_range_values() { - if (m_show_custom_range && m_custom_range_panel) { + if (m_custom_range_panel) { return m_custom_range_panel->get_values(); } return wxArrayString(); } +CalibMode CalibrationPresetPage::get_pa_cali_method() +{ + if (m_pa_cali_method_combox) { + wxString selected_mode = m_pa_cali_method_combox->get_value(); + if (selected_mode == PA_LINE) { + return CalibMode::Calib_PA_Line; + } + else if (selected_mode == PA_PATTERN) { + return CalibMode::Calib_PA_Pattern; + } + } + return CalibMode::Calib_PA_Line; +} + MaxVolumetricSpeedPresetPage::MaxVolumetricSpeedPresetPage( wxWindow *parent, CalibMode cali_mode, bool custom_range, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) : CalibrationPresetPage(parent, cali_mode, custom_range, id, pos, size, style) diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.hpp b/src/slic3r/GUI/CalibrationWizardPresetPage.hpp index 2816c4d7d7..76bf2c1d92 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.hpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.hpp @@ -40,6 +40,29 @@ protected: float m_flow_ratio_value; }; +class CaliComboBox : public wxPanel +{ +public: + CaliComboBox(wxWindow *parent, + wxString title, + wxArrayString values, + int default_index = 0, // default delected id + std::function on_value_change = nullptr, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL); + + wxString get_value() const; + void set_values(const wxArrayString& values); + +private: + wxBoxSizer* m_top_sizer; + wxString m_title; + ComboBox* m_combo_box; + std::function m_on_value_change_call_back; +}; + class CaliPresetWarningPanel : public wxPanel { public: @@ -181,6 +204,7 @@ public: std::string get_print_preset_name(); wxArrayString get_custom_range_values(); + CalibMode get_pa_cali_method(); CaliPresetPageStatus get_page_status() { return m_page_status; } protected: @@ -227,6 +251,7 @@ protected: CaliPresetPageStatus get_status() { return m_page_status; } CaliPageStepGuide* m_step_panel{ nullptr }; + CaliComboBox * m_pa_cali_method_combox{nullptr}; CaliPresetCaliStagePanel* m_cali_stage_panel { nullptr }; wxPanel* m_selection_panel { nullptr }; wxPanel* m_filament_from_panel { nullptr }; diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.cpp b/src/slic3r/GUI/CalibrationWizardSavePage.cpp index 315d55b3c9..d2e027286b 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.cpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.cpp @@ -462,10 +462,10 @@ void CaliPASaveManualPanel::create_panel(wxWindow* parent) auto complete_text_panel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); complete_text_panel->SetBackgroundColour(*wxWHITE); wxBoxSizer* complete_text_sizer = new wxBoxSizer(wxVERTICAL); - auto complete_text = new Label(complete_text_panel, _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); + m_complete_text = new Label(complete_text_panel, _L("Please find the best line on your plate")); + m_complete_text->SetFont(Label::Head_14); + m_complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH); + complete_text_sizer->Add(m_complete_text, 0); complete_text_panel->SetSizer(complete_text_sizer); m_top_sizer->Add(complete_text_panel, 0, wxEXPAND, 0); @@ -523,6 +523,21 @@ void CaliPASaveManualPanel::set_save_img() { } } +void CaliPASaveManualPanel::set_pa_cali_method(ManualPaCaliMethod method) +{ + if (method == ManualPaCaliMethod::PA_LINE) { + m_complete_text->SetLabel(_L("Please find the best line on your plate")); + set_save_img(); + } else if (method == ManualPaCaliMethod::PA_PATTERN) { + m_complete_text->SetLabel(_L("Please find the cornor with perfect degree of extrusion")); + if (wxGetApp().app_config->get_language_code() == "zh-cn") { + m_picture_panel->set_img(create_scaled_bitmap("fd_pattern_manual_result_CN", nullptr, 350)); + } else { + m_picture_panel->set_img(create_scaled_bitmap("fd_pattern_manual_result", nullptr, 350)); + } + } +} + void CaliPASaveManualPanel::set_default_name(const wxString& name) { m_save_name_input->GetTextCtrl()->SetValue(name); } @@ -610,10 +625,10 @@ void CaliPASaveP1PPanel::create_panel(wxWindow* parent) auto complete_text_panel = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); complete_text_panel->SetBackgroundColour(*wxWHITE); wxBoxSizer* complete_text_sizer = new wxBoxSizer(wxVERTICAL); - auto complete_text = new Label(complete_text_panel, _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, wxEXPAND); + m_complete_text = new Label(complete_text_panel, _L("Please find the best line on your plate")); + m_complete_text->SetFont(Label::Head_14); + m_complete_text->Wrap(CALIBRATION_TEXT_MAX_LENGTH); + complete_text_sizer->Add(m_complete_text, 0, wxEXPAND); complete_text_panel->SetSizer(complete_text_sizer); m_top_sizer->Add(complete_text_panel, 0, wxEXPAND, 0); @@ -662,6 +677,22 @@ void CaliPASaveP1PPanel::set_save_img() { } } +void CaliPASaveP1PPanel::set_pa_cali_method(ManualPaCaliMethod method) +{ + if (method == ManualPaCaliMethod::PA_LINE) { + m_complete_text->SetLabel(_L("Please find the best line on your plate")); + set_save_img(); + } + else if (method == ManualPaCaliMethod::PA_PATTERN) { + m_complete_text->SetLabel(_L("Please find the cornor with perfect degree of extrusion")); + if (wxGetApp().app_config->get_language_code() == "zh-cn") { + m_picture_panel->set_img(create_scaled_bitmap("fd_pattern_manual_result_CN", nullptr, 350)); + } else { + m_picture_panel->set_img(create_scaled_bitmap("fd_pattern_manual_result", nullptr, 350)); + } + } +} + bool CaliPASaveP1PPanel::get_result(float* out_k, float* out_n){ // Check if the value is valid if (!CalibUtils::validate_input_k_value(m_k_val->GetTextCtrl()->GetValue(), out_k)) { @@ -808,6 +839,7 @@ void CalibrationPASavePage::sync_cali_result(MachineObject* obj) void CalibrationPASavePage::show_panels(CalibrationMethod method, const PrinterSeries printer_ser) { if (printer_ser == PrinterSeries::SERIES_X1) { if (method == CalibrationMethod::CALI_METHOD_MANUAL) { + m_manual_panel->set_pa_cali_method(curr_obj->manual_pa_cali_method); m_manual_panel->Show(); m_auto_panel->Show(false); } @@ -820,10 +852,12 @@ void CalibrationPASavePage::show_panels(CalibrationMethod method, const PrinterS else if (printer_ser == PrinterSeries::SERIES_P1P) { m_auto_panel->Show(false); m_manual_panel->Show(false); + m_p1p_panel->set_pa_cali_method(curr_obj->manual_pa_cali_method); m_p1p_panel->Show(); } else { m_auto_panel->Show(false); m_manual_panel->Show(false); + m_p1p_panel->set_pa_cali_method(curr_obj->manual_pa_cali_method); m_p1p_panel->Show(); assert(false); } diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.hpp b/src/slic3r/GUI/CalibrationWizardSavePage.hpp index a65465d822..6396d12e78 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.hpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.hpp @@ -119,6 +119,7 @@ public: long style = wxTAB_TRAVERSAL); void create_panel(wxWindow* parent); void set_save_img(); + void set_pa_cali_method(ManualPaCaliMethod method); void set_machine_obj(MachineObject* obj) { m_obj = obj; } @@ -130,6 +131,7 @@ public: protected: wxBoxSizer* m_top_sizer; + Label * m_complete_text; CaliPagePicture* m_picture_panel; ::TextInput* m_save_name_input; ::TextInput* m_k_val; @@ -149,11 +151,13 @@ public: long style = wxTAB_TRAVERSAL); void create_panel(wxWindow* parent); void set_save_img(); + void set_pa_cali_method(ManualPaCaliMethod method); bool get_result(float* out_k, float* out_n); protected: wxBoxSizer* m_top_sizer; + Label * m_complete_text; CaliPagePicture* m_picture_panel; ::TextInput* m_k_val; ::TextInput* m_n_val; diff --git a/src/slic3r/GUI/CalibrationWizardStartPage.cpp b/src/slic3r/GUI/CalibrationWizardStartPage.cpp index a15d59edfb..551cd6c5be 100644 --- a/src/slic3r/GUI/CalibrationWizardStartPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardStartPage.cpp @@ -155,17 +155,11 @@ void CalibrationPAStartPage::on_device_connected(MachineObject* obj) m_action_panel->bind_button(CaliPageActionType::CALI_ACTION_AUTO_CALI, false); } } - else if (obj->get_printer_series() == PrinterSeries::SERIES_P1P) { + else if (obj->get_printer_series() == PrinterSeries::SERIES_P1P || obj->get_printer_arch() == PrinterArch::ARCH_I3) { m_action_panel->show_button(CaliPageActionType::CALI_ACTION_MANAGE_RESULT, false); m_action_panel->show_button(CaliPageActionType::CALI_ACTION_AUTO_CALI, false); m_action_panel->show_button(CaliPageActionType::CALI_ACTION_MANUAL_CALI, true); - - if (!obj->is_function_supported(PrinterFunction::FUNC_EXTRUSION_CALI)) { - m_action_panel->bind_button(CaliPageActionType::CALI_ACTION_MANUAL_CALI, true); - } - else { - m_action_panel->bind_button(CaliPageActionType::CALI_ACTION_MANUAL_CALI, false); - } + m_action_panel->bind_button(CaliPageActionType::CALI_ACTION_MANUAL_CALI, false); } //is support auto cali diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 077e53849d..3b9003dbc3 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -174,6 +174,11 @@ enum AmsOptionType { AMS_OP_CALIBRATE_REMAIN }; +enum ManualPaCaliMethod { + PA_LINE = 0, + PA_PATTERN, +}; + class AmsTray { public: AmsTray(std::string tray_id) { @@ -645,6 +650,7 @@ public: float cache_flow_ratio { 0.0 }; bool cali_finished = true; + ManualPaCaliMethod manual_pa_cali_method = ManualPaCaliMethod::PA_LINE; bool has_get_pa_calib_tab{ false }; std::vector pa_calib_tab; float pa_calib_tab_nozzle_dia; diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index fade099ccb..8b6d9be67b 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -28,6 +28,10 @@ static std::string MachineBedTypeString[5] = { std::string get_calib_mode_name(CalibMode cali_mode, int stage) { switch(cali_mode) { + case CalibMode::Calib_PA_Line: + return "pa_line_calib_mode"; + case CalibMode::Calib_PA_Pattern: + return "pa_pattern_calib_mode"; case CalibMode::Calib_Flow_Rate: if (stage == 1) return "flow_rate_coarse_calib_mode"; @@ -51,7 +55,15 @@ std::string get_calib_mode_name(CalibMode cali_mode, int stage) CalibMode CalibUtils::get_calib_mode_by_name(const std::string name, int& cali_stage) { - if (name == "flow_rate_coarse_calib_mode") { + if (name == "pa_line_calib_mode") { + cali_stage = 0; + return CalibMode::Calib_PA_Line; + } + else if (name == "pa_pattern_calib_mode") { + cali_stage = 1; + return CalibMode::Calib_PA_Line; + } + else if (name == "flow_rate_coarse_calib_mode") { cali_stage = 1; return CalibMode::Calib_Flow_Rate; } @@ -443,16 +455,78 @@ void CalibUtils::calib_flowrate(int pass, const CalibInfo& calib_info, std::stri send_to_print(calib_info, error_message, pass); } +void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model) +{ + DynamicPrintConfig& print_config = calib_info.print_prest->config; + DynamicPrintConfig& filament_config = calib_info.filament_prest->config; + DynamicPrintConfig& printer_config = calib_info.printer_prest->config; + + DynamicPrintConfig full_config; + full_config.apply(FullPrintConfig::defaults()); + full_config.apply(print_config); + full_config.apply(filament_config); + full_config.apply(printer_config); + + float nozzle_diameter = printer_config.option("nozzle_diameter")->get_at(0); + + for (const auto opt : SuggestedConfigCalibPAPattern().float_pairs) { + print_config.set_key_value(opt.first, new ConfigOptionFloat(opt.second)); + } + + print_config.set_key_value("outer_wall_speed", + new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed( + full_config, print_config.get_abs_value("line_width"), + print_config.get_abs_value("layer_height"), 0))); + + for (const auto opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) { + print_config.set_key_value(opt.first, new ConfigOptionFloat(nozzle_diameter * opt.second / 100)); + } + + for (const auto opt : SuggestedConfigCalibPAPattern().int_pairs) { + print_config.set_key_value(opt.first, new ConfigOptionInt(opt.second)); + } + + print_config.set_key_value(SuggestedConfigCalibPAPattern().brim_pair.first, + new ConfigOptionEnum(SuggestedConfigCalibPAPattern().brim_pair.second)); + + //DynamicPrintConfig full_config; + full_config.apply(FullPrintConfig::defaults()); + full_config.apply(print_config); + full_config.apply(filament_config); + full_config.apply(printer_config); + + Vec3d plate_origin(0, 0, 0); + CalibPressureAdvancePattern pa_pattern(calib_info.params, full_config, true, model, plate_origin); + + Pointfs bedfs = full_config.opt("printable_area")->values; + double current_width = bedfs[2].x() - bedfs[0].x(); + double current_depth = bedfs[2].y() - bedfs[0].y(); + Vec3d half_pattern_size = Vec3d(pa_pattern.print_size_x() / 2, pa_pattern.print_size_y() / 2, 0); + Vec3d offset = Vec3d(current_width / 2, current_depth / 2, 0) - half_pattern_size; + pa_pattern.set_start_offset(offset); + + pa_pattern.generate_custom_gcodes(full_config, true, model, plate_origin); + model.calib_pa_pattern = std::make_unique(pa_pattern); +} + void CalibUtils::calib_generic_PA(const CalibInfo &calib_info, std::string &error_message) { const Calib_Params ¶ms = calib_info.params; - if (params.mode != CalibMode::Calib_PA_Line) + if (params.mode != CalibMode::Calib_PA_Line && params.mode != CalibMode::Calib_PA_Pattern) return; Model model; - std::string input_file = Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.stl"; + std::string input_file; + if (params.mode == CalibMode::Calib_PA_Line) + input_file = Slic3r::resources_dir() + "/calib/pressure_advance/pressure_advance_test.stl"; + else if (params.mode == CalibMode::Calib_PA_Pattern) + input_file = Slic3r::resources_dir() + "/calib/pressure_advance/pa_pattern.3mf"; + read_model_from_file(input_file, model); + if (params.mode == CalibMode::Calib_PA_Pattern) + calib_pa_pattern(calib_info, model); + DynamicPrintConfig print_config = calib_info.print_prest->config; DynamicPrintConfig filament_config = calib_info.filament_prest->config; DynamicPrintConfig printer_config = calib_info.printer_prest->config; @@ -763,8 +837,13 @@ void CalibUtils::process_and_store_3mf(Model* model, const DynamicPrintConfig& f plate_size[1] = bedfs[2].y() - bedfs[0].y(); plate_size[2] = print_height; - // todo: adjust the objects position - if (model->objects.size() == 1) { + if (params.mode == CalibMode::Calib_PA_Pattern) { + ModelInstance *instance = model->objects[0]->instances[0]; + Vec3d offset = model->calib_pa_pattern->get_start_offset() + + Vec3d(model->calib_pa_pattern->handle_xy_size() / 2, -model->calib_pa_pattern->handle_xy_size() / 2 - model->calib_pa_pattern->handle_spacing(), 0); + instance->set_offset(offset); + } + else if (model->objects.size() == 1) { ModelInstance *instance = model->objects[0]->instances[0]; instance->set_offset(instance->get_offset() + Vec3d(current_width / 2, current_depth / 2, 0)); } else { diff --git a/src/slic3r/Utils/CalibUtils.hpp b/src/slic3r/Utils/CalibUtils.hpp index 5dee64714e..1d8562b25e 100644 --- a/src/slic3r/Utils/CalibUtils.hpp +++ b/src/slic3r/Utils/CalibUtils.hpp @@ -50,6 +50,8 @@ public: static bool get_flow_ratio_calib_results(std::vector &flow_ratio_calib_results); static void calib_flowrate(int pass, const CalibInfo& calib_info, std::string& error_message); + static void calib_pa_pattern(const CalibInfo &calib_info, Model &model); + static void calib_generic_PA(const CalibInfo& calib_info, std::string &error_message); static void calib_temptue(const CalibInfo& calib_info, std::string& error_message); static void calib_max_vol_speed(const CalibInfo& calib_info, std::string& error_message);