diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 201caf832..dea6871db 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -405,6 +405,11 @@ bool MachineObject::check_valid_ip() return true; } +void MachineObject::_parse_print_option_ack(int option) +{ + xcam_auto_recovery_step_loss = ((option >> (int)PRINT_OP_AUTO_RECOVERY) & 0x01) != 0; +} + void MachineObject::_parse_tray_now(std::string tray_now) { m_tray_now = tray_now; @@ -1122,6 +1127,12 @@ void MachineObject::parse_state_changed_event() void MachineObject::parse_status(int flag) { + if (xcam_auto_recovery_hold_count > 0) + xcam_auto_recovery_hold_count--; + else { + xcam_auto_recovery_step_loss = ((flag >> 4) & 0x1) != 0; + } + camera_recording = ((flag >> 5) & 0x1) != 0; ams_calibrate_remain_flag = ((flag >> 7) & 0x1) != 0; } @@ -1466,6 +1477,17 @@ int MachineObject::command_set_printing_speed(PrintingSpeedLevel lvl) return this->publish_json(j.dump()); } +int MachineObject::command_set_printing_option(bool auto_recovery) +{ + int print_option = (int)auto_recovery << (int)PRINT_OP_AUTO_RECOVERY; + json j; + j["print"]["command"] = "print_option"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["option"] = print_option; + + return this->publish_json(j.dump()); +} + int MachineObject::command_axis_control(std::string axis, double unit, double value, int speed) { char cmd[256]; @@ -1540,30 +1562,52 @@ int MachineObject::command_ipcam_timelapse(bool on_off) return this->publish_json(j.dump()); } -int MachineObject::command_xcam_control(std::string module_name, bool on_off, bool print_halt) +int MachineObject::command_xcam_control(std::string module_name, bool on_off, std::string lvl) { json j; j["xcam"]["command"] = "xcam_control_set"; j["xcam"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); j["xcam"]["module_name"] = module_name; j["xcam"]["control"] = on_off; - j["xcam"]["print_halt"] = print_halt; + j["xcam"]["enable"] = on_off; //old protocol + j["xcam"]["print_halt"] = true; //old protocol + if (!lvl.empty()) { + j["xcam"]["halt_print_sensitivity"] = lvl; + } + BOOST_LOG_TRIVIAL(info) << "command:xcam_control_set" << ", sequence_id:" << std::to_string(MachineObject::m_sequence_id)<< + ", module_name:" << module_name << ", control:" << on_off << ", halt_print_sensitivity:" << lvl; return this->publish_json(j.dump()); } +int MachineObject::command_xcam_control_ai_monitoring(bool on_off, std::string lvl) +{ + bool print_halt = (lvl == "never_halt") ? false:true; + + xcam_ai_monitoring = on_off; + xcam_ai_monitoring_hold_count = HOLD_COUNT_MAX; + xcam_ai_monitoring_sensitivity = lvl; + return command_xcam_control("printing_monitor", on_off, lvl); +} + +int MachineObject::command_xcam_control_buildplate_marker_detector(bool on_off) +{ + xcam_buildplate_marker_detector = on_off; + xcam_buildplate_marker_hold_count = HOLD_COUNT_MAX; + return command_xcam_control("buildplate_marker_detector", on_off); +} + int MachineObject::command_xcam_control_first_layer_inspector(bool on_off, bool print_halt) { xcam_first_layer_inspector = on_off; xcam_first_layer_hold_count = HOLD_COUNT_MAX; - return command_xcam_control("first_layer_inspector", on_off, print_halt); + return command_xcam_control("first_layer_inspector", on_off); } -int MachineObject::command_xcam_control_spaghetti_detector(bool on_off, bool print_halt) +int MachineObject::command_xcam_control_auto_recovery_step_loss(bool on_off) { - xcam_spaghetti_detector = on_off; - xcam_spaghetti_print_halt = print_halt; - xcam_spaghetti_hold_count = HOLD_COUNT_MAX; - return command_xcam_control("spaghetti_detector", on_off, print_halt); + xcam_auto_recovery_step_loss = on_off; + xcam_auto_recovery_hold_count = HOLD_COUNT_MAX; + return command_set_printing_option(on_off); } void MachineObject::set_bind_status(std::string status) @@ -1763,8 +1807,14 @@ bool MachineObject::is_function_supported(PrinterFunction func) case FUNC_FIRSTLAYER_INSPECT: func_name = "FUNC_FIRSTLAYER_INSPECT"; break; - case FUNC_SPAGHETTI: - func_name = "FUNC_SPAGHETTI"; + case FUNC_AI_MONITORING: + func_name = "FUNC_AI_MONITORING"; + break; + case FUNC_BUILDPLATE_MARKER_DETECT: + func_name = "FUNC_BUILDPLATE_MARKER_DETECT"; + break; + case FUNC_AUTO_RECOVERY_STEP_LOSS: + func_name = "FUNC_AUTO_RECOVERY_STEP_LOSS"; break; case FUNC_FLOW_CALIBRATION: func_name = "FUNC_FLOW_CALIBRATION"; @@ -2279,6 +2329,27 @@ int MachineObject::parse_json(std::string payload) try { if (jj.contains("xcam")) { + if (xcam_ai_monitoring_hold_count > 0) + xcam_ai_monitoring_hold_count--; + else { + if (jj["xcam"].contains("printing_monitor")) { + // new protocol + xcam_ai_monitoring = jj["xcam"]["printing_monitor"].get(); + } else { + // old version protocol + if (jj["xcam"].contains("spaghetti_detector")) { + xcam_ai_monitoring = jj["xcam"]["spaghetti_detector"].get(); + if (jj["xcam"].contains("print_halt")) { + bool print_halt = jj["xcam"]["print_halt"].get(); + if (print_halt) { xcam_ai_monitoring_sensitivity = "medium"; } + } + } + } + if (jj["xcam"].contains("halt_print_sensitivity")) { + xcam_ai_monitoring_sensitivity = jj["xcam"]["halt_print_sensitivity"].get(); + } + } + if (xcam_first_layer_hold_count > 0) xcam_first_layer_hold_count--; else { @@ -2287,14 +2358,11 @@ int MachineObject::parse_json(std::string payload) } } - if (xcam_spaghetti_hold_count > 0) { - xcam_spaghetti_hold_count--; - } else { - if (jj["xcam"].contains("spaghetti_detector")) { - xcam_spaghetti_detector = jj["xcam"]["spaghetti_detector"].get(); - } - if (jj["xcam"].contains("print_halt")) { - xcam_spaghetti_print_halt = jj["xcam"]["print_halt"].get(); + if (xcam_buildplate_marker_hold_count > 0) + xcam_buildplate_marker_hold_count--; + else { + if (jj["xcam"].contains("buildplate_marker_detector")) { + xcam_buildplate_marker_detector = jj["xcam"]["buildplate_marker_detector"].get(); } } } @@ -2614,17 +2682,54 @@ int MachineObject::parse_json(std::string payload) } } } else if (jj["command"].get() == "xcam_control_set") { - if (jj.contains("module_name") && jj.contains("control")) { - if (jj["module_name"].get() == "first_layer_inspector") { - xcam_first_layer_inspector = jj["control"].get(); - xcam_first_layer_hold_count = HOLD_COUNT_MAX; - } else if (jj["module_name"].get() == "spaghetti_detector") { - xcam_spaghetti_detector = jj["control"].get(); - xcam_spaghetti_hold_count = HOLD_COUNT_MAX; - if (jj.contains("print_halt")) - xcam_spaghetti_print_halt = jj["print_halt"].get(); + if (jj.contains("module_name")) { + if (jj.contains("enable") || jj.contains("control")) { + bool enable = false; + if (jj.contains("enable")) + enable = jj["enable"].get(); + else if (jj.contains("control")) + enable = jj["control"].get(); + else { + ; + } + + if (jj["module_name"].get() == "first_layer_inspector") { + xcam_first_layer_inspector = enable; + xcam_first_layer_hold_count = HOLD_COUNT_MAX; + } + else if (jj["module_name"].get() == "buildplate_marker_detector") { + xcam_buildplate_marker_detector = enable; + xcam_buildplate_marker_hold_count = HOLD_COUNT_MAX; + } + else if (jj["module_name"].get() == "printing_monitor") { + xcam_ai_monitoring = enable; + xcam_ai_monitoring_hold_count = HOLD_COUNT_MAX; + if (jj.contains("halt_print_sensitivity")) { + xcam_ai_monitoring_sensitivity = jj["halt_print_sensitivity"].get(); + } + } + else if (jj["module_name"].get() == "spaghetti_detector") { + // old protocol + xcam_ai_monitoring = enable; + xcam_ai_monitoring_hold_count = HOLD_COUNT_MAX; + if (jj.contains("print_halt")) { + if (jj["print_halt"].get()) + xcam_ai_monitoring_sensitivity = "medium"; + } + } } } + }else if(jj["command"].get() == "print_option") { + try { + if (jj.contains("option")) { + if (jj["option"].is_number()) { + int option = jj["option"].get(); + _parse_print_option_ack(option); + } + } + } + catch(...) { + } } } } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index d576bd736..8e0545937 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -61,7 +61,9 @@ enum PrinterFunction { FUNC_TIMELAPSE, FUNC_RECORDING, FUNC_FIRSTLAYER_INSPECT, - FUNC_SPAGHETTI, + FUNC_AI_MONITORING, + FUNC_BUILDPLATE_MARKER_DETECT, + FUNC_AUTO_RECOVERY_STEP_LOSS, FUNC_FLOW_CALIBRATION, FUNC_AUTO_LEVELING, FUNC_CHAMBER_TEMP, @@ -297,6 +299,8 @@ private: NetworkAgent* m_agent { nullptr }; bool check_valid_ip(); + void _parse_print_option_ack(int option); + public: enum LIGHT_EFFECT { @@ -326,6 +330,11 @@ public: }; enum ExtruderAxisStatus extruder_axis_status = LOAD; + enum PrintOption { + PRINT_OP_AUTO_RECOVERY = 0, + PRINT_OP_MAX, + }; + class ModuleVersionInfo { public: @@ -522,9 +531,14 @@ public: bool camera_has_sdcard { false }; bool xcam_first_layer_inspector { false }; int xcam_first_layer_hold_count = 0; - bool xcam_spaghetti_detector { false }; - bool xcam_spaghetti_print_halt{ false }; - int xcam_spaghetti_hold_count = 0; + + bool xcam_ai_monitoring{ false }; + int xcam_ai_monitoring_hold_count = 0; + std::string xcam_ai_monitoring_sensitivity; + bool xcam_buildplate_marker_detector{ false }; + int xcam_buildplate_marker_hold_count = 0; + bool xcam_auto_recovery_step_loss{ false }; + int xcam_auto_recovery_hold_count = 0; /* HMS */ std::vector hms_list; @@ -593,6 +607,9 @@ public: // set printing speed int command_set_printing_speed(PrintingSpeedLevel lvl); + // set print option + int command_set_printing_option(bool auto_recovery); + // axis string is X, Y, Z, E int command_axis_control(std::string axis, double unit = 1.0f, double value = 1.0f, int speed = 3000); @@ -604,9 +621,11 @@ public: // camera control int command_ipcam_record(bool on_off); int command_ipcam_timelapse(bool on_off); - int command_xcam_control(std::string module_name, bool on_off, bool print_halt); + int command_xcam_control(std::string module_name, bool on_off, std::string lvl = ""); + int command_xcam_control_ai_monitoring(bool on_off, std::string lvl); int command_xcam_control_first_layer_inspector(bool on_off, bool print_halt); - int command_xcam_control_spaghetti_detector(bool on_off, bool print_halt); + int command_xcam_control_buildplate_marker_detector(bool on_off); + int command_xcam_control_auto_recovery_step_loss(bool on_off); /* common apis */ inline bool is_local() { return !dev_ip.empty(); } diff --git a/src/slic3r/GUI/PrintOptionsDialog.cpp b/src/slic3r/GUI/PrintOptionsDialog.cpp index 101b129b9..289f919fb 100644 --- a/src/slic3r/GUI/PrintOptionsDialog.cpp +++ b/src/slic3r/GUI/PrintOptionsDialog.cpp @@ -6,6 +6,7 @@ #define DLG_SIZE (wxSize(FromDIP(360), FromDIP(160))) static const wxColour STATIC_BOX_LINE_COL = wxColour(238, 238, 238); +static const wxColour STATIC_TEXT_CAPTION_COL = wxColour(100, 100, 100); namespace Slic3r { namespace GUI { @@ -27,6 +28,18 @@ PrintOptionsDialog::PrintOptionsDialog(wxWindow* parent) m_options_sizer->Fit(this); this->Fit(); + m_cb_ai_monitoring->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) { + if (obj) { + int level = ai_monitoring_level_list->GetSelection(); + std::string lvl = sensitivity_level_to_msg_string((AiMonitorSensitivityLevel) level); + if (!lvl.empty()) + obj->command_xcam_control_ai_monitoring(m_cb_ai_monitoring->GetValue(), lvl); + else + BOOST_LOG_TRIVIAL(warning) << "print_option: lvl = " << lvl; + } + evt.Skip(); + }); + m_cb_first_layer->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) { if (obj) { obj->command_xcam_control_first_layer_inspector(m_cb_first_layer->GetValue(), false); @@ -34,102 +47,185 @@ PrintOptionsDialog::PrintOptionsDialog(wxWindow* parent) evt.Skip(); }); - m_cb_spaghetti->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) { - update_spaghetti(); - + m_cb_auto_recovery->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) { if (obj) { - obj->command_xcam_control_spaghetti_detector(m_cb_spaghetti->GetValue(), m_cb_spaghetti_print_halt->GetValue()); + obj->command_xcam_control_auto_recovery_step_loss(m_cb_auto_recovery->GetValue()); } evt.Skip(); }); - m_cb_spaghetti_print_halt->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent&evt) { + m_cb_plate_mark->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) { if (obj) { - obj->command_xcam_control_spaghetti_detector(m_cb_spaghetti->GetValue(), m_cb_spaghetti_print_halt->GetValue()); + obj->command_xcam_control_buildplate_marker_detector(m_cb_plate_mark->GetValue()); } evt.Skip(); }); } -PrintOptionsDialog::~PrintOptionsDialog() {} +PrintOptionsDialog::~PrintOptionsDialog() +{ + ai_monitoring_level_list->Disconnect( wxEVT_COMBOBOX, wxCommandEventHandler(PrintOptionsDialog::set_ai_monitor_sensitivity), NULL, this ); +} -void PrintOptionsDialog::on_dpi_changed(const wxRect &suggested_rect) +void PrintOptionsDialog::on_dpi_changed(const wxRect& suggested_rect) { this->SetMinSize(DLG_SIZE); this->SetSize(DLG_SIZE); Fit(); } -void PrintOptionsDialog::update_spaghetti() +void PrintOptionsDialog::update_ai_monitor_status() { - if (m_cb_spaghetti->GetValue()) { - m_cb_spaghetti_print_halt->Enable(); - text_spaghetti_print_halt->Enable(); + if (m_cb_ai_monitoring->GetValue()) { + ai_monitoring_level_list->Enable(); } else { - m_cb_spaghetti_print_halt->Disable(); - text_spaghetti_print_halt->Disable(); + ai_monitoring_level_list->Disable(); } } -void PrintOptionsDialog::update_options(MachineObject *obj_) +void PrintOptionsDialog::update_options(MachineObject* obj_) { if (!obj_) return; + if (obj_->is_function_supported(PrinterFunction::FUNC_AI_MONITORING)) { + text_ai_monitoring->Show(); + m_cb_ai_monitoring->Show(); + text_ai_monitoring_caption->Show(); + ai_monitoring_level_list->Show(); + line1->Show(); + } + else { + text_ai_monitoring->Hide(); + m_cb_ai_monitoring->Hide(); + text_ai_monitoring_caption->Hide(); + ai_monitoring_level_list->Hide(); + line1->Hide(); + } + + if (obj_->is_function_supported(PrinterFunction::FUNC_BUILDPLATE_MARKER_DETECT)) { + text_plate_mark->Show(); + m_cb_plate_mark->Show(); + text_plate_mark_caption->Show(); + line2->Show(); + } + else { + text_plate_mark->Hide(); + m_cb_plate_mark->Hide(); + text_plate_mark_caption->Hide(); + line2->Hide(); + } + if (obj_->is_function_supported(PrinterFunction::FUNC_FIRSTLAYER_INSPECT)) { text_first_layer->Show(); m_cb_first_layer->Show(); - } else { + line3->Show(); + } + else { text_first_layer->Hide(); m_cb_first_layer->Hide(); + line3->Hide(); } - if (obj_->is_function_supported(PrinterFunction::FUNC_SPAGHETTI)) { - text_spaghetti->Show(); - m_cb_spaghetti->Show(); - m_cb_spaghetti_print_halt->Show(); - text_spaghetti_print_halt->Show(); - }else { - text_spaghetti->Hide(); - m_cb_spaghetti->Hide(); - m_cb_spaghetti_print_halt->Hide(); - text_spaghetti_print_halt->Hide(); + if (obj_->is_function_supported(PrinterFunction::FUNC_AUTO_RECOVERY_STEP_LOSS)) { + text_auto_recovery->Show(); + m_cb_auto_recovery->Show(); + line4->Show(); + } + else { + text_auto_recovery->Hide(); + m_cb_auto_recovery->Hide(); + line4->Hide(); } this->Freeze(); - m_cb_spaghetti->SetValue(obj_->xcam_spaghetti_detector); - m_cb_spaghetti_print_halt->SetValue(obj_->xcam_spaghetti_print_halt); + + auto test1 = obj_->xcam_first_layer_inspector; + auto test2 = obj_->xcam_buildplate_marker_detector; + auto test3 = obj_->xcam_auto_recovery_step_loss; m_cb_first_layer->SetValue(obj_->xcam_first_layer_inspector); - update_spaghetti(); + m_cb_plate_mark->SetValue(obj_->xcam_buildplate_marker_detector); + m_cb_auto_recovery->SetValue(obj_->xcam_auto_recovery_step_loss); + + m_cb_ai_monitoring->SetValue(obj_->xcam_ai_monitoring); + for (auto i = AiMonitorSensitivityLevel::LOW; i < LEVELS_NUM; i = (AiMonitorSensitivityLevel) (i + 1)) { + if (sensitivity_level_to_msg_string(i) == obj_->xcam_ai_monitoring_sensitivity) { + ai_monitoring_level_list->SetSelection((int)i); + break; + } + } + + update_ai_monitor_status(); this->Thaw(); } wxBoxSizer* PrintOptionsDialog::create_settings_group(wxWindow* parent) { - auto sizer = new wxBoxSizer(wxVERTICAL); - auto line_sizer = new wxBoxSizer(wxHORIZONTAL); - m_cb_spaghetti = new CheckBox(parent); - text_spaghetti = new wxStaticText(parent, wxID_ANY, _L("Spaghetti and Excess Chute Pileup Detection")); - text_spaghetti->SetFont(Label::Body_14); + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* line_sizer = new wxBoxSizer(wxHORIZONTAL); + + // ai monitoring with levels + line_sizer = new wxBoxSizer(wxHORIZONTAL); + m_cb_ai_monitoring = new CheckBox(parent); + text_ai_monitoring = new wxStaticText(parent, wxID_ANY, _L("Enable AI monitoring of printing")); + text_ai_monitoring->SetFont(Label::Body_14); line_sizer->Add(FromDIP(5), 0, 0, 0); - line_sizer->Add(m_cb_spaghetti, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); - line_sizer->Add(text_spaghetti, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(m_cb_ai_monitoring, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(text_ai_monitoring, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); sizer->Add(line_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); + line_sizer->Add(FromDIP(5), 0, 0, 0); line_sizer = new wxBoxSizer(wxHORIZONTAL); - m_cb_spaghetti_print_halt = new CheckBox(parent); - text_spaghetti_print_halt = new wxStaticText(parent, wxID_ANY, _L("Stop printing when Spaghetti or Excess Chute Pileup is detected")); - text_spaghetti_print_halt->SetFont(Label::Body_14); + text_ai_monitoring_caption = new wxStaticText(parent, wxID_ANY, _L("Sensitivity of pausing is")); + text_ai_monitoring_caption->SetFont(Label::Body_14); + text_ai_monitoring_caption->SetForegroundColour(STATIC_TEXT_CAPTION_COL); + text_ai_monitoring_caption->Wrap(-1); + + ai_monitoring_level_list = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(120),-1), 0, NULL, wxCB_READONLY ); + for (auto i = AiMonitorSensitivityLevel::LOW; i < LEVELS_NUM; i = (AiMonitorSensitivityLevel) (i + 1)) { + wxString level_option = sensitivity_level_to_label_string(i); + ai_monitoring_level_list->Append(level_option); + } + line_sizer->Add(FromDIP(30), 0, 0, 0); - line_sizer->Add(m_cb_spaghetti_print_halt, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); - line_sizer->Add(text_spaghetti_print_halt, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); - + line_sizer->Add(text_ai_monitoring_caption, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add( ai_monitoring_level_list, 0, wxEXPAND|wxALL, FromDIP(5) ); sizer->Add(line_sizer, 0, wxEXPAND | wxALL , 0); - sizer->Add(0, FromDIP(10), 0, 0); - StaticLine* line = new StaticLine(parent, false); - line->SetLineColour(STATIC_BOX_LINE_COL); - sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); + line1 = new StaticLine(parent, false); + line1->SetLineColour(STATIC_BOX_LINE_COL); + sizer->Add(line1, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); + // detection of build plate position + line_sizer = new wxBoxSizer(wxHORIZONTAL); + m_cb_plate_mark = new CheckBox(parent); + text_plate_mark = new wxStaticText(parent, wxID_ANY, _L("Enable detection of build plate position")); + text_plate_mark->SetFont(Label::Body_14); + line_sizer->Add(FromDIP(5), 0, 0, 0); + line_sizer->Add(m_cb_plate_mark, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(text_plate_mark, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + sizer->Add(line_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); + line_sizer->Add(FromDIP(5), 0, 0, 0); + + line_sizer = new wxBoxSizer(wxHORIZONTAL); + wxString caption_text = _L( + "The localization tag of build plate is detected, and printing is paused if the tag is not in predefined range." + ); + caption_text = format_text(text_plate_mark, caption_text, FromDIP(250)); + text_plate_mark_caption = new wxStaticText(parent, wxID_ANY, caption_text); + if (is_english_text(caption_text)) { + text_plate_mark_caption->Wrap(FromDIP(250)); + } + text_plate_mark_caption->SetFont(Label::Body_14); + text_plate_mark_caption->SetForegroundColour(STATIC_TEXT_CAPTION_COL); + line_sizer->Add(FromDIP(30), 0, 0, 0); + line_sizer->Add(text_plate_mark_caption, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + sizer->Add(line_sizer, 0, wxEXPAND | wxALL , FromDIP(5)); + + line2 = new StaticLine(parent, false); + line2->SetLineColour(STATIC_BOX_LINE_COL); + sizer->Add(line2, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); + + // detection of first layer line_sizer = new wxBoxSizer(wxHORIZONTAL); m_cb_first_layer = new CheckBox(parent); text_first_layer = new wxStaticText(parent, wxID_ANY, _L("First Layer Inspection")); @@ -137,12 +233,73 @@ wxBoxSizer* PrintOptionsDialog::create_settings_group(wxWindow* parent) line_sizer->Add(FromDIP(5), 0, 0, 0); line_sizer->Add(m_cb_first_layer, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); line_sizer->Add(text_first_layer, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); - sizer->Add(line_sizer, 1, wxEXPAND | wxALL, FromDIP(5)); + sizer->Add(line_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); line_sizer->Add(FromDIP(5), 0, 0, 0); + line3 = new StaticLine(parent, false); + line3->SetLineColour(STATIC_BOX_LINE_COL); + sizer->Add(line3, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); + + // auto-recovery from step loss + line_sizer = new wxBoxSizer(wxHORIZONTAL); + m_cb_auto_recovery = new CheckBox(parent); + text_auto_recovery = new wxStaticText(parent, wxID_ANY, _L("Auto-recovery from step loss")); + text_auto_recovery->SetFont(Label::Body_14); + line_sizer->Add(FromDIP(5), 0, 0, 0); + line_sizer->Add(m_cb_auto_recovery, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + line_sizer->Add(text_auto_recovery, 1, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + sizer->Add(line_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); + line_sizer->Add(FromDIP(5), 0, 0, 0); + + line4 = new StaticLine(parent, false); + line4->SetLineColour(wxColour(255,255,255)); + sizer->Add(line4, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20)); + + ai_monitoring_level_list->Connect( wxEVT_COMBOBOX, wxCommandEventHandler(PrintOptionsDialog::set_ai_monitor_sensitivity), NULL, this ); + return sizer; } +wxString PrintOptionsDialog::sensitivity_level_to_label_string(enum AiMonitorSensitivityLevel level) { + switch (level) { + case LOW: + return _L("Low"); + case MEDIUM: + return _L("Medium"); + case HIGH: + return _L("High"); + default: + return _L(""); + } + return ""; +} + +std::string PrintOptionsDialog::sensitivity_level_to_msg_string(enum AiMonitorSensitivityLevel level) { + switch (level) { + case LOW: + return "low"; + case MEDIUM: + return "medium"; + case HIGH: + return "high"; + default: + return ""; + } + return ""; +} + +void PrintOptionsDialog::set_ai_monitor_sensitivity(wxCommandEvent& evt) +{ + int level = ai_monitoring_level_list->GetSelection(); + std::string lvl = sensitivity_level_to_msg_string((AiMonitorSensitivityLevel)level); + + if (obj && !lvl.empty()) { + obj->command_xcam_control_ai_monitoring(m_cb_ai_monitoring->GetValue(), lvl); + } else { + BOOST_LOG_TRIVIAL(warning) << "print_option: obj is null or lvl = " << lvl; + } +} + void PrintOptionsDialog::update_machine_obj(MachineObject *obj_) { obj = obj_; @@ -154,4 +311,50 @@ bool PrintOptionsDialog::Show(bool show) return DPIDialog::Show(show); } +bool PrintOptionsDialog::is_english_text(wxString str) +{ + std::regex reg("^[0-9a-zA-Z]+$"); + std::smatch matchResult; + + std::string pattern_Special = "{}[]<>~!@#$%^&*(),.?/ :"; + for (auto i = 0; i < str.Length(); i++) { + std::string regex_str = wxString(str[i]).ToStdString(); + if(std::regex_match(regex_str, matchResult, reg)){ + continue; + } + else { + int result = pattern_Special.find(regex_str.c_str()); + if (result < 0 || result > pattern_Special.length()) { + return false; + } + } + } + return true; +} + +wxString PrintOptionsDialog::format_text(wxStaticText* st, wxString str, int warp) +{ + if (is_english_text(str)) return str; + + wxString out_txt = str; + wxString count_txt = ""; + int new_line_pos = 0; + + for (int i = 0; i < str.length(); i++) { + if (str[i] == '\n') { + count_txt = ""; + continue; + } + auto text_size = st->GetTextExtent(count_txt); + if (text_size.x < warp) { + count_txt += str[i]; + } + else { + out_txt.insert(i - 1, '\n'); + count_txt = ""; + } + } + return out_txt; +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/PrintOptionsDialog.hpp b/src/slic3r/GUI/PrintOptionsDialog.hpp index 14fb97e9c..0a2300816 100644 --- a/src/slic3r/GUI/PrintOptionsDialog.hpp +++ b/src/slic3r/GUI/PrintOptionsDialog.hpp @@ -14,6 +14,7 @@ #include "Widgets/Label.hpp" #include "Widgets/CheckBox.hpp" #include "Widgets/StaticLine.hpp" +#include "Widgets/ComboBox.hpp" namespace Slic3r { namespace GUI { @@ -22,18 +23,32 @@ class PrintOptionsDialog : public DPIDialog protected: // settings CheckBox* m_cb_first_layer; - CheckBox* m_cb_spaghetti; - CheckBox* m_cb_spaghetti_print_halt; + CheckBox* m_cb_ai_monitoring; + CheckBox* m_cb_plate_mark; + CheckBox* m_cb_auto_recovery; wxStaticText* text_first_layer; - wxStaticText* text_spaghetti; - wxStaticText* text_spaghetti_print_halt; + wxStaticText* text_ai_monitoring; + wxStaticText* text_ai_monitoring_caption; + ComboBox* ai_monitoring_level_list; + wxStaticText* text_plate_mark; + wxStaticText* text_plate_mark_caption; + wxStaticText* text_auto_recovery; + StaticLine* line1; + StaticLine* line2; + StaticLine* line3; + StaticLine* line4; wxBoxSizer* create_settings_group(wxWindow* parent); + bool print_halt = false; + + bool is_english_text(wxString str); + wxString format_text(wxStaticText* st, wxString str, int warp); + public: PrintOptionsDialog(wxWindow* parent); ~PrintOptionsDialog(); void on_dpi_changed(const wxRect &suggested_rect) override; - void update_spaghetti(); + void update_ai_monitor_status(); MachineObject *obj { nullptr }; @@ -42,6 +57,16 @@ public: void update_options(MachineObject *obj_); void update_machine_obj(MachineObject *obj_); bool Show(bool show) override; + + enum AiMonitorSensitivityLevel { + LOW = 0, + MEDIUM = 1, + HIGH = 2, + LEVELS_NUM = 3 + }; + wxString sensitivity_level_to_label_string(enum AiMonitorSensitivityLevel level); + std::string sensitivity_level_to_msg_string(enum AiMonitorSensitivityLevel level); + void set_ai_monitor_sensitivity(wxCommandEvent& evt); }; }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index a056a1bdb..51843837d 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -1339,7 +1339,9 @@ void StatusPanel::update(MachineObject *obj) if (obj->is_function_supported(PrinterFunction::FUNC_FIRSTLAYER_INSPECT) - || obj->is_function_supported(PrinterFunction::FUNC_SPAGHETTI)) { + || obj->is_function_supported(PrinterFunction::FUNC_AI_MONITORING) + || obj->is_function_supported(PrinterFunction::FUNC_BUILDPLATE_MARKER_DETECT) + || obj->is_function_supported(PrinterFunction::FUNC_AUTO_RECOVERY_STEP_LOSS)) { m_options_btn->Show(); if (print_options_dlg == nullptr) { print_options_dlg = new PrintOptionsDialog(this);