Skip to content

Commit

Permalink
Various improvements to SimplyPrint integration (SoftFever/OrcaSlicer…
Browse files Browse the repository at this point in the history
…#4831)

Note: Does not compile.

* Allow using BBL's device tab when 3rd party print host is used

* Add option to open SimplyPrint panel in device tab after uploading

* Fix default print host for prusa connect

* Do not set api key in device view when SimplyPrint is used

* Sending 3mf file to SimplyPrint when using BBL printers

* Fix file extension when uploading 3mf

* Prepare for large file uploading

* Implement chunk upload

* Fix file uploading exceeding content size

* Fix wrong field type

* Add `temp=true` to all chunk upload calls

* Add macro to enable test api

* Merge branch 'main' into dev/simplyprint-improve

* Fix another missing `temp=true`

* Add delete token

* Try fixing build error on *nix systems

* Merge branch 'main' into dev/simplyprint-improve

* Merge branch 'main' into dev/simplyprint-improve

* Merge remote-tracking branch 'remote/main' into dev/simplyprint-improve

# Conflicts:
#	src/slic3r/GUI/BackgroundSlicingProcess.cpp

* Move the `bbl_use_print_host_webui` option to print host dialog. Also make it a derived option of `print_host_webui` instead.

* Merge branch 'main' into dev/simplyprint-improve

# Conflicts:
#	src/slic3r/GUI/MainFrame.cpp
#	src/slic3r/GUI/Plater.cpp

* Merge branch 'main' into dev/simplyprint-improve

# Conflicts:
#	src/slic3r/GUI/Plater.cpp

* Use a more generic option instead of SimplyPrint specific

* Merge branch 'main' into dev/simplyprint-improve

* Merge branch 'main' into dev/simplyprint-improve

(cherry picked from commit cd6cd0786fc494d2f1e2fd2123e791f65fbcc97a)
Co-authored-by: Ocraftyone <ocraftyone@users.noreply.github.com>
  • Loading branch information
Noisyfox and Ocraftyone committed Jul 22, 2024
1 parent 8ca2f1d commit 3411a75
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 74 deletions.
24 changes: 12 additions & 12 deletions src/slic3r/GUI/BackgroundSlicingProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ BackgroundSlicingProcess::BackgroundSlicingProcess()
m_temp_output_path = temp_path.string();
}

BackgroundSlicingProcess::~BackgroundSlicingProcess()
{
BackgroundSlicingProcess::~BackgroundSlicingProcess()
{
this->stop();
this->join_background_thread();
boost::nowide::remove(m_temp_output_path.c_str());
Expand Down Expand Up @@ -161,7 +161,7 @@ void BackgroundSlicingProcess::process_fff()
m_print->process();
wxCommandEvent evt(m_event_slicing_completed_id);
// Post the Slicing Finished message for the G-code viewer to update.
// Passing the timestamp
// Passing the timestamp
evt.SetInt((int)(m_fff_print->step_state_with_timestamp(PrintStep::psSlicingFinished).timestamp));
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, [this](const ThumbnailsParams& params) { return this->render_thumbnails(params); });
Expand Down Expand Up @@ -261,7 +261,7 @@ void BackgroundSlicingProcess::thread_proc()
if (m_print->cancel_status() != Print::CANCELED_INTERNAL) {
// Only post the canceled event, if canceled by user.
// Don't post the canceled event, if canceled from Print::apply().
SlicingProcessCompletedEvent evt(m_event_finished_id, 0,
SlicingProcessCompletedEvent evt(m_event_finished_id, 0,
(m_state == STATE_CANCELED) ? SlicingProcessCompletedEvent::Cancelled :
exception ? SlicingProcessCompletedEvent::Error : SlicingProcessCompletedEvent::Finished, exception);
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
Expand Down Expand Up @@ -540,7 +540,7 @@ void BackgroundSlicingProcess::stop_internal()
m_print->set_cancel_callback([](){});
}

// Execute task from background thread on the UI thread. Returns true if processed, false if cancelled.
// Execute task from background thread on the UI thread. Returns true if processed, false if cancelled.
bool BackgroundSlicingProcess::execute_ui_task(std::function<void()> task)
{
bool running = false;
Expand Down Expand Up @@ -613,7 +613,7 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn
assert(m_print != nullptr);
assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology());
Print::ApplyStatus invalidated = m_print->apply(model, config);
if (physical_printer_config &&
if (physical_printer_config &&
(m_print->physical_printer_config().diff(*physical_printer_config).size() != 0 || m_print->physical_printer_config().keys() != physical_printer_config->keys()) ) {
m_print->physical_printer_config().clear();
m_print->physical_printer_config().apply(*physical_printer_config);
Expand Down Expand Up @@ -646,7 +646,7 @@ void BackgroundSlicingProcess::set_task(const PrintBase::TaskParams &params)

// Set the output path of the G-code.
void BackgroundSlicingProcess::schedule_export(const std::string &path, bool export_path_on_removable_media)
{
{
assert(m_export_path.empty());
if (! m_export_path.empty())
return;
Expand Down Expand Up @@ -691,17 +691,17 @@ void BackgroundSlicingProcess::reset_export()
}

bool BackgroundSlicingProcess::set_step_started(BackgroundSlicingProcessStep step)
{
{
return m_step_state.set_started(step, m_print->state_mutex(), [this](){ this->throw_if_canceled(); });
}

void BackgroundSlicingProcess::set_step_done(BackgroundSlicingProcessStep step)
{
{
m_step_state.set_done(step, m_print->state_mutex(), [this](){ this->throw_if_canceled(); });
}

bool BackgroundSlicingProcess::is_step_done(BackgroundSlicingProcessStep step) const
{
{
return m_step_state.is_done(step, m_print->state_mutex());
}

Expand All @@ -712,7 +712,7 @@ bool BackgroundSlicingProcess::invalidate_step(BackgroundSlicingProcessStep step
}

bool BackgroundSlicingProcess::invalidate_all_steps()
{
{
return m_step_state.invalidate_all([this](){ this->stop_internal(); });
}

Expand Down Expand Up @@ -796,7 +796,7 @@ void BackgroundSlicingProcess::prepare_upload()
throw Slic3r::RuntimeError(_utf8(L("Copying of the temporary G-code to the output G-code failed")));
m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string());
// Make a copy of the source path, as run_post_process_scripts() is allowed to change it when making a copy of the source file
// (not here, but when the final target is a file).
// (not here, but when the final target is a file).
std::string source_path_str = source_path.string();
std::string output_name_str = m_upload_job.upload_data.upload_path.string();
if (run_post_process_scripts(source_path_str, false, m_upload_job.printhost->get_name(), output_name_str, m_fff_print->full_print_config()))
Expand Down
14 changes: 2 additions & 12 deletions src/slic3r/GUI/PhysicalPrinterDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,6 @@ void PhysicalPrinterDialog::update(bool printer_change)
m_optgroup->show_field("host_type");

m_optgroup->enable_field("print_host");
m_optgroup->enable_field("print_host_webui");
m_optgroup->enable_field("printhost_cafile");
m_optgroup->enable_field("printhost_ssl_ignore_revoke");
if (m_printhost_cafile_browse_btn)
Expand All @@ -648,21 +647,12 @@ void PhysicalPrinterDialog::update(bool printer_change)
if (Field* printhost_field = m_optgroup->get_field("print_host"); printhost_field) {
if (wxTextCtrl* temp = dynamic_cast<TextCtrl*>(printhost_field)->text_ctrl(); temp) {
const auto current_host = temp->GetValue();
if (current_host == "https://simplyprint.io") {
if (current_host == "https://simplyprint.io" || current_host == "https://simplyprint.io/panel") {
temp->SetValue(wxString());
}
}
}
if (Field* printhost_webui_field = m_optgroup->get_field("print_host_webui"); printhost_webui_field) {
if (wxTextCtrl* temp = dynamic_cast<TextCtrl*>(printhost_webui_field)->text_ctrl(); temp) {
const auto current_host = temp->GetValue();
if (current_host == "https://simplyprint.io/panel") {
temp->SetValue(wxString());
}
}
}
if (opt && opt->value == htPrusaLink)
{
if (opt->value == htPrusaLink) { // PrusaConnect does NOT allow http digest
m_optgroup->show_field("printhost_authorization_type");
AuthorizationType auth_type = m_config->option<ConfigOptionEnum<AuthorizationType>>("printhost_authorization_type")->value;
m_optgroup->show_field("printhost_apikey", auth_type == AuthorizationType::atKeyPassword);
Expand Down
10 changes: 5 additions & 5 deletions src/slic3r/GUI/Plater.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class Sidebar : public wxPanel
ObjectLayers* obj_layers();
wxScrolledWindow* scrolled_panel();
wxPanel* presets_panel();

ConfigOptionsGroup* og_freq_chng_params(PrinterTechnology tech);
wxButton* get_wiping_dialog_button();
void update_objects_list_extruder_column(size_t extruders_count);
Expand Down Expand Up @@ -267,7 +267,7 @@ class Plater: public wxPanel
bool undo_redo_string_getter(const bool is_undo, int idx, const char** out_text);
void undo_redo_topmost_string_getter(const bool is_undo, std::string& out_text);
bool search_string_getter(int idx, const char** label, const char** tooltip);
// For the memory statistics.
// For the memory statistics.
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
void clear_undo_redo_stack_main();
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
Expand All @@ -291,14 +291,14 @@ class Plater: public wxPanel
void set_project_filename(const wxString& filename);

bool is_export_gcode_scheduled() const;

const Selection& get_selection() const;
int get_selected_object_idx();
bool is_single_full_object_selection() const;
GLCanvas3D* canvas3D();
const GLCanvas3D * canvas3D() const;
GLCanvas3D* get_current_canvas3D();

void arrange();
void find_new_position(const ModelInstancePtrs &instances);

Expand Down Expand Up @@ -382,7 +382,7 @@ class Plater: public wxPanel
void init_notification_manager();

void bring_instance_forward();

// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
class SuppressSnapshots
{
Expand Down
4 changes: 2 additions & 2 deletions src/slic3r/GUI/PrintHostDialogs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
}
});
txt_filename->SetFocus();

if (post_actions.has(PrintHostPostUploadAction::StartPrint)) {
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Print"));
btn_print->Bind(wxEVT_BUTTON, [this, validate_path](wxCommandEvent&) {
Expand All @@ -116,7 +116,7 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
if (validate_path(txt_filename->GetValue())) {
post_upload_action = PrintHostPostUploadAction::StartSimulation;
EndDialog(wxID_OK);
}
}
});
}

Expand Down
77 changes: 61 additions & 16 deletions src/slic3r/Utils/Http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ struct CurlGlobalInit

std::unique_ptr<CurlGlobalInit> CurlGlobalInit::instance;

struct form_file
{
fs::ifstream ifs;
boost::filesystem::ifstream::off_type init_offset;
size_t content_length;
};

struct Http::priv
{
enum {
Expand All @@ -149,7 +156,7 @@ struct Http::priv
std::string buffer;
// Used for storing file streams added as multipart form parts
// Using a deque here because unlike vector it doesn't ivalidate pointers on insertion
std::deque<fs::ifstream> form_files;
std::deque<form_file> form_files;
std::string postfields;
std::string error_buffer; // Used for CURLOPT_ERRORBUFFER
size_t limit;
Expand All @@ -173,7 +180,10 @@ struct Http::priv

void set_timeout_connect(long timeout);
void set_timeout_max(long timeout);
void form_add_file(const char *name, const fs::path &path, const char* filename);
void form_add_file(const char *name, const fs::path &path, const char* filename, boost::filesystem::ifstream::off_type offset, size_t length);
/* mime */
void mime_form_add_text(const char* name, const char* value);
void mime_form_add_file(const char* name, const char* path);
void set_post_body(const fs::path &path);
void set_post_body(const std::string &body);
void set_put_body(const fs::path &path);
Expand Down Expand Up @@ -275,15 +285,27 @@ int Http::priv::xfercb_legacy(void *userp, double dltotal, double dlnow, double

size_t Http::priv::form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp)
{
auto stream = reinterpret_cast<fs::ifstream*>(userp);
auto f = reinterpret_cast<form_file*>(userp);

try {
stream->read(buffer, size * nitems);
size_t max_read_size = size * nitems;
if (f->content_length == 0) {
// Unlimited
f->ifs.read(buffer, max_read_size);
} else {
unsigned long long read_size = f->ifs.tellg() - f->init_offset;
if (read_size >= f->content_length) {
return 0;
}

max_read_size = std::min(max_read_size, size_t(f->content_length - read_size));
f->ifs.read(buffer, max_read_size);
}
} catch (const std::exception &) {
return CURL_READFUNC_ABORT;
}

return stream->gcount();
return f->ifs.gcount();
}

void Http::priv::set_timeout_connect(long timeout)
Expand All @@ -296,7 +318,7 @@ void Http::priv::set_timeout_max(long timeout)
::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
}

void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename)
void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename, boost::filesystem::ifstream::off_type offset, size_t length)
{
// We can't use CURLFORM_FILECONTENT, because curl doesn't support Unicode filenames on Windows
// and so we use CURLFORM_STREAM with boost ifstream to read the file.
Expand All @@ -305,18 +327,21 @@ void Http::priv::form_add_file(const char *name, const fs::path &path, const cha
filename = path.string().c_str();
}

form_files.emplace_back(path, std::ios::in | std::ios::binary);
auto &stream = form_files.back();
stream.seekg(0, std::ios::end);
size_t size = stream.tellg();
stream.seekg(0);
form_files.emplace_back(form_file{{path, std::ios::in | std::ios::binary}, offset, length});
auto &f = form_files.back();
size_t size = length;
if (length == 0) {
f.ifs.seekg(0, std::ios::end);
size = f.ifs.tellg() - offset;
}
f.ifs.seekg(offset);

if (filename != nullptr) {
::curl_formadd(&form, &form_end,
CURLFORM_COPYNAME, name,
CURLFORM_FILENAME, filename,
CURLFORM_CONTENTTYPE, "application/octet-stream",
CURLFORM_STREAM, static_cast<void*>(&stream),
CURLFORM_STREAM, static_cast<void*>(&f),
CURLFORM_CONTENTSLENGTH, static_cast<long>(size),
CURLFORM_END
);
Expand Down Expand Up @@ -545,15 +570,35 @@ Http& Http::form_add(const std::string &name, const std::string &contents)
return *this;
}

Http& Http::form_add_file(const std::string &name, const fs::path &path)
Http& Http::form_add_file(const std::string &name, const fs::path &path, boost::filesystem::ifstream::off_type offset, size_t length)
{
if (p) { p->form_add_file(name.c_str(), path.c_str(), nullptr, offset, length); }
return *this;
}


Http& Http::mime_form_add_text(std::string &name, std::string &value)
{
if (p) { p->mime_form_add_text(name.c_str(), value.c_str()); }
return *this;
}

Http& Http::mime_form_add_file(std::string &name, const char* path)
{
if (p) { p->mime_form_add_file(name.c_str(), path); }
return *this;
}


Http& Http::form_add_file(const std::wstring& name, const fs::path& path, boost::filesystem::ifstream::off_type offset, size_t length)
{
if (p) { p->form_add_file(name.c_str(), path.c_str(), nullptr); }
if (p) { p->form_add_file((char*)name.c_str(), path.c_str(), nullptr, offset, length); }
return *this;
}

Http& Http::form_add_file(const std::string &name, const fs::path &path, const std::string &filename)
Http& Http::form_add_file(const std::string &name, const fs::path &path, const std::string &filename, boost::filesystem::ifstream::off_type offset, size_t length)
{
if (p) { p->form_add_file(name.c_str(), path.c_str(), filename.c_str()); }
if (p) { p->form_add_file(name.c_str(), path.c_str(), filename.c_str(), offset, length); }
return *this;
}

Expand Down
12 changes: 9 additions & 3 deletions src/slic3r/Utils/Http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,18 @@ class Http : public std::enable_shared_from_this<Http> {
// Add a HTTP multipart form field
Http& form_add(const std::string &name, const std::string &contents);
// Add a HTTP multipart form file data contents, `name` is the name of the part
Http& form_add_file(const std::string &name, const boost::filesystem::path &path);
Http& form_add_file(const std::string &name, const boost::filesystem::path &path, boost::filesystem::ifstream::off_type offset = 0, size_t length = 0);
// Add a HTTP mime form field
Http& mime_form_add_text(std::string& name, std::string& value);
// Add a HTTP mime form file
Http& mime_form_add_file(std::string& name, const char* path);
// Same as above except also override the file's filename with a wstring type
Http& form_add_file(const std::wstring& name, const boost::filesystem::path& path, boost::filesystem::ifstream::off_type offset = 0, size_t length = 0);
// Same as above except also override the file's filename with a custom one
Http& form_add_file(const std::string &name, const boost::filesystem::path &path, const std::string &filename);
Http& form_add_file(const std::string &name, const boost::filesystem::path &path, const std::string &filename, boost::filesystem::ifstream::off_type offset = 0, size_t length = 0);

#ifdef WIN32
// Tells libcurl to ignore certificate revocation checks in case of missing or offline distribution points for those SSL backends where such behavior is present.
// Tells libcurl to ignore certificate revocation checks in case of missing or offline distribution points for those SSL backends where such behavior is present.
// This option is only supported for Schannel (the native Windows SSL library).
Http& ssl_revoke_best_effort(bool set);
#endif // WIN32
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/Utils/PrintHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "MKS.hpp"
#include "SimplyPrint.hpp"
#include "../GUI/PrintHostDialogs.hpp"
#include "../GUI/MainFrame.hpp"
#include "../GUI/GUI.hpp"
#include "slic3r/GUI/I18N.hpp"

Expand Down
6 changes: 5 additions & 1 deletion src/slic3r/Utils/PrintHost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ENABLE_ENUM_BITMASK_OPERATORS(PrintHostPostUploadAction);

struct PrintHostUpload
{
bool use_3mf;
boost::filesystem::path source_path;
boost::filesystem::path upload_path;

Expand Down Expand Up @@ -79,13 +80,15 @@ struct PrintHostJob
{
PrintHostUpload upload_data;
std::unique_ptr<PrintHost> printhost;
bool switch_to_device_tab{false};
bool cancelled = false;

PrintHostJob() {}
PrintHostJob(const PrintHostJob&) = delete;
PrintHostJob(PrintHostJob &&other)
: upload_data(std::move(other.upload_data))
, printhost(std::move(other.printhost))
, switch_to_device_tab(other.switch_to_device_tab)
, cancelled(other.cancelled)
{}

Expand All @@ -97,7 +100,8 @@ struct PrintHostJob
PrintHostJob& operator=(PrintHostJob &&other)
{
upload_data = std::move(other.upload_data);
printhost = std::move(other.printhost);
printhost = std::move(other.printhost);
switch_to_device_tab = other.switch_to_device_tab;
cancelled = other.cancelled;
return *this;
}
Expand Down
Loading

0 comments on commit 3411a75

Please sign in to comment.