NEW: support send gcode to third-party printer

Thanks SoftForever for your works to support
sending a gcode file to third-party printer

Change-Id: I3cba43c8bd878f1f1c2fd5fae202ed4d922e8727
Signed-off-by: Stone Li <stone.li@bambulab.com>
This commit is contained in:
Stone Li 2022-09-19 09:18:48 +08:00 committed by Lane.Wei
parent 52cdf4930d
commit 91d5ba2870
29 changed files with 3067 additions and 40 deletions

View file

@ -125,6 +125,9 @@
#include "libslic3r/Platform.hpp"
#include "nlohmann/json.hpp"
#include "PhysicalPrinterDialog.hpp"
#include "PrintHostDialogs.hpp"
using boost::optional;
namespace fs = boost::filesystem;
using Slic3r::_3DScene;
@ -502,12 +505,23 @@ Sidebar::Sidebar(Plater *parent)
combo_printer->edit_btn = edit_btn;
p->combo_printer = combo_printer;
connection_btn = new ScalableButton(p->m_panel_printer_content, wxID_ANY, "monitor_signal_strong");
connection_btn->SetBackgroundColour(wxColour(255, 255, 255));
connection_btn->SetToolTip(_L("Connection"));
connection_btn->Bind(wxEVT_BUTTON, [this, combo_printer](wxCommandEvent)
{
PhysicalPrinterDialog dlg(this->GetParent());
dlg.ShowModal();
});
wxBoxSizer* vsizer_printer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* hsizer_printer = new wxBoxSizer(wxHORIZONTAL);
hsizer_printer->Add(combo_printer, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
hsizer_printer->Add(edit_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
hsizer_printer->Add(FromDIP(8), 0, 0, 0, 0);
hsizer_printer->Add(connection_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(3));
hsizer_printer->Add(FromDIP(8), 0, 0, 0, 0);
vsizer_printer->Add(hsizer_printer, 0, wxEXPAND, 0);
// Bed type selection
@ -893,6 +907,9 @@ void Sidebar::update_all_preset_comboboxes()
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
const auto print_tech = preset_bundle.printers.get_edited_preset().printer_technology();
//only show connection button for not-BBL printer
update_printer_host_icon();
// Update the print choosers to only contain the compatible presets, update the dirty flags.
//BBS
@ -1296,6 +1313,19 @@ void Sidebar::enable_buttons(bool enable)
#endif
}
void Sidebar::update_printer_host_icon() {
bool is_bbl_vendor_preset = false;
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
if (preset_bundle) {
is_bbl_vendor_preset = preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(preset_bundle);
}
if (is_bbl_vendor_preset) {
connection_btn->Hide();
}else{
connection_btn->Show();
}
}
bool Sidebar::show_reslice(bool show) const { return p->btn_reslice->Show(show); }
bool Sidebar::show_export(bool show) const { return p->btn_export_gcode->Show(show); }
bool Sidebar::show_send(bool show) const { return p->btn_send_gcode->Show(show); }
@ -1779,6 +1809,8 @@ struct Plater::priv
}
}
void export_gcode(fs::path output_path, bool output_path_on_removable_media);
void export_gcode(fs::path output_path, bool output_path_on_removable_media, PrintHostJob upload_job);
void reload_from_disk();
bool replace_volume_with_stl(int object_idx, int volume_idx, const fs::path& new_path, const std::string& snapshot = "");
void replace_with_stl();
@ -1835,6 +1867,8 @@ struct Plater::priv
void on_action_print_plate(SimpleEvent&);
void on_action_print_all(SimpleEvent&);
void on_action_export_gcode(SimpleEvent&);
void on_action_send_gcode(SimpleEvent&);
void on_action_upload_gcode(SimpleEvent&);
void on_action_export_sliced_file(SimpleEvent&);
void on_action_select_sliced_plate(wxCommandEvent& evt);
@ -2223,6 +2257,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
q->Bind(EVT_GLTOOLBAR_SELECT_SLICED_PLATE, &priv::on_action_select_sliced_plate, this);
q->Bind(EVT_GLTOOLBAR_PRINT_ALL, &priv::on_action_print_all, this);
q->Bind(EVT_GLTOOLBAR_EXPORT_GCODE, &priv::on_action_export_gcode, this);
q->Bind(EVT_GLTOOLBAR_SEND_GCODE, &priv::on_action_send_gcode, this);
q->Bind(EVT_GLTOOLBAR_UPLOAD_GCODE, &priv::on_action_upload_gcode, this);
q->Bind(EVT_GLTOOLBAR_EXPORT_SLICED_FILE, &priv::on_action_export_sliced_file, this);
q->Bind(EVT_GLTOOLBAR_SEND_TO_PRINTER, &priv::on_action_export_to_sdcard, this);
q->Bind(EVT_GLCANVAS_PLATE_SELECT, &priv::on_plate_selected, this);
@ -4152,7 +4188,38 @@ void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_remova
this->background_process.set_task(PrintBase::TaskParams());
this->restart_background_process(priv::UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT);
}
void Plater::priv::export_gcode(fs::path output_path, bool output_path_on_removable_media, PrintHostJob upload_job)
{
wxCHECK_RET(!(output_path.empty() && upload_job.empty()), "export_gcode: output_path and upload_job empty");
if (model.objects.empty())
return;
if (background_process.is_export_scheduled()) {
GUI::show_error(q, _L("Another export job is currently running."));
return;
}
// bitmask of UpdateBackgroundProcessReturnState
unsigned int state = update_background_process(true);
if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE)
view3D->reload_scene(false);
if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0)
return;
show_warning_dialog = true;
if (! output_path.empty()) {
background_process.schedule_export(output_path.string(), output_path_on_removable_media);
notification_manager->push_delayed_notification(NotificationType::ExportOngoing, []() {return true; }, 1000, 0);
} else {
background_process.schedule_upload(std::move(upload_job));
}
// If the SLA processing of just a single object's supports is running, restart slicing for the whole object.
this->background_process.set_task(PrintBase::TaskParams());
this->restart_background_process(priv::UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT);
}
unsigned int Plater::priv::update_restart_background_process(bool force_update_scene, bool force_update_preview)
{
bool switch_print = true;
@ -5639,6 +5706,22 @@ void Plater::priv::on_action_export_gcode(SimpleEvent&)
}
}
void Plater::priv::on_action_upload_gcode(SimpleEvent&)
{
if (q != nullptr) {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n";
q->send_gcode_legacy(-1, nullptr, true);
}
}
void Plater::priv::on_action_send_gcode(SimpleEvent&)
{
if (q != nullptr) {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received export gcode event\n" ;
q->send_gcode_legacy(-1, nullptr, false);
}
}
void Plater::priv::on_action_export_sliced_file(SimpleEvent&)
{
if (q != nullptr) {
@ -8919,7 +9002,53 @@ void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &
// and let the background processing start.
this->p->restart_background_process(state | priv::UPDATE_BACKGROUND_PROCESS_FORCE_RESTART);
}
void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool upload_only)
{
// if physical_printer is selected, send gcode for this printer
// DynamicPrintConfig* physical_printer_config = wxGetApp().preset_bundle->physical_printers.get_selected_printer_config();
DynamicPrintConfig* physical_printer_config = &Slic3r::GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config;
if (! physical_printer_config || p->model.objects.empty())
return;
PrintHostJob upload_job(physical_printer_config);
if (upload_job.empty())
return;
// Obtain default output path
fs::path default_output_file;
try {
// Update the background processing, so that the placeholder parser will get the correct values for the ouput file template.
// Also if there is something wrong with the current configuration, a pop-up dialog will be shown and the export will not be performed.
unsigned int state = this->p->update_restart_background_process(false, false);
if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID)
return;
default_output_file = this->p->background_process.output_filepath_for_project(into_path(get_project_filename(".3mf")));
} catch (const Slic3r::PlaceholderParserError& ex) {
// Show the error with monospaced font.
show_error(this, ex.what(), true);
return;
} catch (const std::exception& ex) {
show_error(this, ex.what(), false);
return;
}
default_output_file = fs::path(Slic3r::fold_utf8_to_ascii(default_output_file.string()));
// Repetier specific: Query the server for the list of file groups.
wxArrayString groups;
{
wxBusyCursor wait;
upload_job.printhost->get_groups(groups);
}
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups, upload_only);
if (dlg.ShowModal() == wxID_OK) {
upload_job.upload_data.upload_path = dlg.filename();
upload_job.upload_data.post_action = dlg.post_action();
upload_job.upload_data.group = dlg.group();
p->export_gcode(fs::path(), false, std::move(upload_job));
}
}
int Plater::send_gcode(int plate_idx, Export3mfProgressFn proFn)
{
int result = 0;