Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Kral <vojtech@kral.hk>2018-04-04 12:18:22 +0300
committerbubnikv <bubnikv@gmail.com>2018-04-04 12:18:22 +0300
commitb0840065ed84f4006207b38de3c9c6a5e15a7071 (patch)
tree3da655b0f6ca247d0f567831a978a73c68246978
parent00324a14b84f47cc6ae1dc92e6582ee6b6171e03 (diff)
Octoprint (#804)
* Octoprint progress dialog * Fix curl version on Windows
-rw-r--r--doc/How to build - Windows.md7
-rw-r--r--doc/deps-build/windows/slic3r-makedeps.ps12
-rw-r--r--lib/Slic3r/GUI/Plater.pm6
-rw-r--r--xs/src/slic3r/Utils/Http.cpp73
-rw-r--r--xs/src/slic3r/Utils/Http.hpp17
-rw-r--r--xs/src/slic3r/Utils/OctoPrint.cpp66
-rw-r--r--xs/src/slic3r/Utils/OctoPrint.hpp2
-rw-r--r--xs/xsp/Utils_OctoPrint.xsp2
8 files changed, 135 insertions, 40 deletions
diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md
index 104720b34..8b7d37cdd 100644
--- a/doc/How to build - Windows.md
+++ b/doc/How to build - Windows.md
@@ -1,8 +1,9 @@
# Building Slic3r PE on Microsoft Windows
-The currently supported way of building Slic3r PE on Windows is with MS Visual Studio 2013
+The currently supported way of building Slic3r PE on Windows is with CMake and MS Visual Studio 2013
using our Perl binary distribution (compiled from official Perl sources).
You can use the free [Visual Studio 2013 Community Edition](https://www.visualstudio.com/vs/older-downloads/).
+CMake installer can be downloaded from [the official website](https://cmake.org/download/).
Other setups (such as mingw + Strawberry Perl) _may_ work, but we cannot guarantee this will work
and cannot provide guidance.
@@ -26,8 +27,8 @@ Apart from wxWidgets and Perl, you will also need additional dependencies:
We have prepared a binary package of the listed libraries:
- - 32 bit: [slic3r-destdir-32.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=slic3r-destdir-32.7z)
- - 64 bit: [slic3r-destdir-64.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=slic3r-destdir-64.7z)
+ - 32 bit: [slic3r-destdir-32.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=2%2Fslic3r-destdir-32.7z)
+ - 64 bit: [slic3r-destdir-64.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=2%2Fslic3r-destdir-64.7z)
It is recommended you unpack this package into `C:\local\` as the environment
setup script expects it there.
diff --git a/doc/deps-build/windows/slic3r-makedeps.ps1 b/doc/deps-build/windows/slic3r-makedeps.ps1
index 8b39cae30..e256d61e4 100644
--- a/doc/deps-build/windows/slic3r-makedeps.ps1
+++ b/doc/deps-build/windows/slic3r-makedeps.ps1
@@ -37,7 +37,7 @@ if ($destdir -eq "") {
}
$BOOST = 'boost_1_63_0'
-$CURL = 'curl-7.28.0'
+$CURL = 'curl-7.58.0'
$TBB_SHA = 'a0dc9bf76d0120f917b641ed095360448cabc85b'
$TBB = "tbb-$TBB_SHA"
diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm
index 0138d3f39..14c2d66ae 100644
--- a/lib/Slic3r/GUI/Plater.pm
+++ b/lib/Slic3r/GUI/Plater.pm
@@ -1481,7 +1481,11 @@ sub on_export_completed {
# Send $self->{send_gcode_file} to OctoPrint.
if ($send_gcode) {
my $op = Slic3r::OctoPrint->new($self->{config});
- $op->send_gcode($self->GetId(), $PROGRESS_BAR_EVENT, $ERROR_EVENT, $self->{send_gcode_file});
+ if ($op->send_gcode($self->{send_gcode_file})) {
+ $self->statusbar->SetStatusText(L("OctoPrint upload finished."));
+ } else {
+ $self->statusbar->SetStatusText("");
+ }
}
$self->{print_file} = undef;
diff --git a/xs/src/slic3r/Utils/Http.cpp b/xs/src/slic3r/Utils/Http.cpp
index de28904e2..0826284d8 100644
--- a/xs/src/slic3r/Utils/Http.cpp
+++ b/xs/src/slic3r/Utils/Http.cpp
@@ -36,16 +36,20 @@ struct Http::priv
::curl_slist *headerlist;
std::string buffer;
size_t limit;
+ bool cancel;
std::thread io_thread;
Http::CompleteFn completefn;
Http::ErrorFn errorfn;
+ Http::ProgressFn progressfn;
priv(const std::string &url);
~priv();
static bool ca_file_supported(::CURL *curl);
static size_t writecb(void *data, size_t size, size_t nmemb, void *userp);
+ static int xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
+ static int xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow);
std::string curl_error(CURLcode curlcode);
std::string body_size_error();
void http_perform();
@@ -55,7 +59,8 @@ Http::priv::priv(const std::string &url) :
curl(::curl_easy_init()),
form(nullptr),
form_end(nullptr),
- headerlist(nullptr)
+ headerlist(nullptr),
+ cancel(false)
{
if (curl == nullptr) {
throw std::runtime_error(std::string("Could not construct Curl object"));
@@ -112,6 +117,24 @@ size_t Http::priv::writecb(void *data, size_t size, size_t nmemb, void *userp)
return realsize;
}
+int Http::priv::xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+{
+ auto self = static_cast<priv*>(userp);
+ bool cb_cancel = false;
+
+ if (self->progressfn) {
+ Progress progress(dltotal, dlnow, ultotal, ulnow);
+ self->progressfn(progress, cb_cancel);
+ }
+
+ return self->cancel || cb_cancel;
+}
+
+int Http::priv::xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+ return xfercb(userp, dltotal, dlnow, ultotal, ulnow);
+}
+
std::string Http::priv::curl_error(CURLcode curlcode)
{
return (boost::format("%1% (%2%)")
@@ -132,6 +155,16 @@ void Http::priv::http_perform()
::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this));
+ ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+#if LIBCURL_VERSION_MAJOR >= 7 && LIBCURL_VERSION_MINOR >= 32
+ ::curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xfercb);
+ ::curl_easy_setopt(curl, CURLOPT_XFERINFODATA, static_cast<void*>(this));
+ (void)xfercb_legacy; // prevent unused function warning
+#else
+ ::curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, xfercb);
+ ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, static_cast<void*>(this));
+#endif
+
#ifndef NDEBUG
::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
#endif
@@ -149,16 +182,16 @@ void Http::priv::http_perform()
::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
if (res != CURLE_OK) {
- std::string error;
- if (res == CURLE_WRITE_ERROR) {
- error = std::move(body_size_error());
+ if (res == CURLE_ABORTED_BY_CALLBACK) {
+ Progress dummyprogress(0, 0, 0, 0);
+ bool cancel = true;
+ if (progressfn) { progressfn(dummyprogress, cancel); }
+ }
+ else if (res == CURLE_WRITE_ERROR) {
+ if (errorfn) { errorfn(std::move(buffer), std::move(body_size_error()), http_status); }
} else {
- error = std::move(curl_error(res));
+ if (errorfn) { errorfn(std::move(buffer), std::move(curl_error(res)), http_status); }
};
-
- if (errorfn) {
- errorfn(std::move(buffer), std::move(error), http_status);
- }
} else {
if (completefn) {
completefn(std::move(buffer), http_status);
@@ -258,6 +291,12 @@ Http& Http::on_error(ErrorFn fn)
return *this;
}
+Http& Http::on_progress(ProgressFn fn)
+{
+ if (p) { p->progressfn = std::move(fn); }
+ return *this;
+}
+
Http::Ptr Http::perform()
{
auto self = std::make_shared<Http>(std::move(*this));
@@ -277,6 +316,11 @@ void Http::perform_sync()
if (p) { p->http_perform(); }
}
+void Http::cancel()
+{
+ if (p) { p->cancel = true; }
+}
+
Http Http::get(std::string url)
{
return std::move(Http{std::move(url)});
@@ -297,5 +341,16 @@ bool Http::ca_file_supported()
return res;
}
+std::ostream& operator<<(std::ostream &os, const Http::Progress &progress)
+{
+ os << "Http::Progress("
+ << "dltotal = " << progress.dltotal
+ << ", dlnow = " << progress.dlnow
+ << ", ultotal = " << progress.ultotal
+ << ", ulnow = " << progress.ulnow
+ << ")";
+ return os;
+}
+
}
diff --git a/xs/src/slic3r/Utils/Http.hpp b/xs/src/slic3r/Utils/Http.hpp
index 6ac5fcce1..7ed8196e6 100644
--- a/xs/src/slic3r/Utils/Http.hpp
+++ b/xs/src/slic3r/Utils/Http.hpp
@@ -14,9 +14,22 @@ class Http : public std::enable_shared_from_this<Http> {
private:
struct priv;
public:
+ struct Progress
+ {
+ size_t dltotal;
+ size_t dlnow;
+ size_t ultotal;
+ size_t ulnow;
+
+ Progress(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) :
+ dltotal(dltotal), dlnow(dlnow), ultotal(ultotal), ulnow(ulnow)
+ {}
+ };
+
typedef std::shared_ptr<Http> Ptr;
typedef std::function<void(std::string /* body */, unsigned /* http_status */)> CompleteFn;
typedef std::function<void(std::string /* body */, std::string /* error */, unsigned /* http_status */)> ErrorFn;
+ typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn;
Http(Http &&other);
@@ -37,9 +50,11 @@ public:
Http& on_complete(CompleteFn fn);
Http& on_error(ErrorFn fn);
+ Http& on_progress(ProgressFn fn);
Ptr perform();
void perform_sync();
+ void cancel();
static bool ca_file_supported();
private:
@@ -48,6 +63,8 @@ private:
std::unique_ptr<priv> p;
};
+std::ostream& operator<<(std::ostream &, const Http::Progress &);
+
}
diff --git a/xs/src/slic3r/Utils/OctoPrint.cpp b/xs/src/slic3r/Utils/OctoPrint.cpp
index 5bf51f470..e63a16c38 100644
--- a/xs/src/slic3r/Utils/OctoPrint.cpp
+++ b/xs/src/slic3r/Utils/OctoPrint.cpp
@@ -1,10 +1,11 @@
#include "OctoPrint.hpp"
-#include <iostream>
+#include <algorithm>
#include <boost/format.hpp>
#include <wx/frame.h>
#include <wx/event.h>
+#include <wx/progdlg.h>
#include "libslic3r/PrintConfig.hpp"
#include "slic3r/GUI/GUI.hpp"
@@ -39,36 +40,53 @@ bool OctoPrint::test(wxString &msg) const
return res;
}
-void OctoPrint::send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print) const
+bool OctoPrint::send_gcode(const std::string &filename, bool print) const
{
+ enum { PROGRESS_RANGE = 1000 };
+
+ const auto errortitle = _(L("Error while uploading to the OctoPrint server"));
+
+ wxProgressDialog progress_dialog(
+ _(L("OctoPrint upload")),
+ _(L("Sending G-code file to the OctoPrint server...")),
+ PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
+ progress_dialog.Pulse();
+
+ wxString test_msg;
+ if (!test(test_msg)) {
+ auto errormsg = wxString::Format("%s: %s", errortitle, test_msg);
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ return false;
+ }
+
+ bool res = true;
+
auto http = Http::post(std::move(make_url("api/files/local")));
set_auth(http);
http.form_add("print", print ? "true" : "false")
.form_add_file("file", filename)
- .on_complete([=](std::string body, unsigned status) {
- wxWindow *window = wxWindow::FindWindowById(windowId);
- if (window == nullptr) { return; }
-
- wxCommandEvent* evt = new wxCommandEvent(completeEvt);
- evt->SetString(_(L("G-code file successfully uploaded to the OctoPrint server")));
- evt->SetInt(100);
- wxQueueEvent(window, evt);
+ .on_complete([&](std::string body, unsigned status) {
+ progress_dialog.Update(PROGRESS_RANGE);
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ auto errormsg = wxString::Format("%s: %s", errortitle, format_error(error, status));
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ res = false;
})
- .on_error([=](std::string body, std::string error, unsigned status) {
- wxWindow *window = wxWindow::FindWindowById(windowId);
- if (window == nullptr) { return; }
-
- wxCommandEvent* evt_complete = new wxCommandEvent(completeEvt);
- evt_complete->SetInt(100);
- wxQueueEvent(window, evt_complete);
-
- wxCommandEvent* evt_error = new wxCommandEvent(errorEvt);
- evt_error->SetString(wxString::Format("%s: %s",
- _(L("Error while uploading to the OctoPrint server")),
- format_error(error, status)));
- wxQueueEvent(window, evt_error);
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ if (cancel) {
+ // Upload was canceled
+ res = false;
+ } else if (progress.ultotal > 0) {
+ int value = PROGRESS_RANGE * progress.ulnow / progress.ultotal;
+ cancel = !progress_dialog.Update(std::min(value, PROGRESS_RANGE - 1)); // Cap the value to prevent premature dialog closing
+ } else {
+ cancel = !progress_dialog.Pulse();
+ }
})
- .perform();
+ .perform_sync();
+
+ return res;
}
void OctoPrint::set_auth(Http &http) const
diff --git a/xs/src/slic3r/Utils/OctoPrint.hpp b/xs/src/slic3r/Utils/OctoPrint.hpp
index 1f544295c..744b4fcc1 100644
--- a/xs/src/slic3r/Utils/OctoPrint.hpp
+++ b/xs/src/slic3r/Utils/OctoPrint.hpp
@@ -17,7 +17,7 @@ public:
OctoPrint(DynamicPrintConfig *config);
bool test(wxString &curl_msg) const;
- void send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print = false) const;
+ bool send_gcode(const std::string &filename, bool print = false) const;
private:
std::string host;
std::string apikey;
diff --git a/xs/xsp/Utils_OctoPrint.xsp b/xs/xsp/Utils_OctoPrint.xsp
index 124f66cb5..282a3055d 100644
--- a/xs/xsp/Utils_OctoPrint.xsp
+++ b/xs/xsp/Utils_OctoPrint.xsp
@@ -9,5 +9,5 @@
OctoPrint(DynamicPrintConfig *config);
~OctoPrint();
- void send_gcode(int windowId, int completeEvt, int errorEvt, std::string filename, bool print = false) const;
+ bool send_gcode(std::string filename, bool print = false) const;
};