Fixing crash on linux. Exporting png in the UI thread.
This commit is contained in:
parent
18bfe4f2dc
commit
4f27f6c6dc
@ -289,16 +289,19 @@ void print_to(Print& print,
|
|||||||
|
|
||||||
int st_prev = 0;
|
int st_prev = 0;
|
||||||
const std::string jobdesc = "Rasterizing and compressing sliced layers";
|
const std::string jobdesc = "Rasterizing and compressing sliced layers";
|
||||||
print.set_status(0, jobdesc);
|
|
||||||
tbb::spin_mutex m;
|
tbb::spin_mutex m;
|
||||||
|
|
||||||
std::vector<long long> keys;
|
std::vector<long long> keys;
|
||||||
keys.reserve(layers.size());
|
keys.reserve(layers.size());
|
||||||
for(auto& e : layers) keys.push_back(e.first);
|
for(auto& e : layers) keys.push_back(e.first);
|
||||||
|
|
||||||
|
int initstatus = print.progressindicator? print.progressindicator->state()
|
||||||
|
: 0;
|
||||||
|
print.set_status(initstatus, jobdesc);
|
||||||
|
|
||||||
// Method that prints one layer
|
// Method that prints one layer
|
||||||
auto process_layer = [&layers, &keys, &printer, &st_prev, &m,
|
auto process_layer = [&layers, &keys, &printer, &st_prev, &m,
|
||||||
&jobdesc, print_bb, dir, cx, cy, &print] (unsigned layer_id)
|
&jobdesc, print_bb, dir, cx, cy, &print, initstatus] (unsigned layer_id)
|
||||||
{
|
{
|
||||||
LayerPtrs lrange = layers[keys[layer_id]];
|
LayerPtrs lrange = layers[keys[layer_id]];
|
||||||
|
|
||||||
@ -345,10 +348,10 @@ void print_to(Print& print,
|
|||||||
|
|
||||||
printer.finishLayer(layer_id); // Finish the layer for later saving it.
|
printer.finishLayer(layer_id); // Finish the layer for later saving it.
|
||||||
|
|
||||||
auto st = static_cast<int>(layer_id*100.0/layers.size());
|
auto st = static_cast<int>(layer_id*80.0/layers.size());
|
||||||
m.lock();
|
m.lock();
|
||||||
if( st - st_prev > 10) {
|
if( st - st_prev > 10) {
|
||||||
print.set_status(st, jobdesc);
|
print.set_status(initstatus + st, jobdesc);
|
||||||
st_prev = st;
|
st_prev = st;
|
||||||
}
|
}
|
||||||
m.unlock();
|
m.unlock();
|
||||||
@ -364,12 +367,12 @@ void print_to(Print& print,
|
|||||||
// Sequential version (for testing)
|
// Sequential version (for testing)
|
||||||
// for(unsigned l = 0; l < layers.size(); ++l) process_layer(l);
|
// for(unsigned l = 0; l < layers.size(); ++l) process_layer(l);
|
||||||
|
|
||||||
print.set_status(100, jobdesc);
|
// print.set_status(100, jobdesc);
|
||||||
|
|
||||||
// Save the print into the file system.
|
// Save the print into the file system.
|
||||||
print.set_status(0, "Writing layers to disk");
|
print.set_status(initstatus + 90, "Writing layers to disk");
|
||||||
printer.save(dir);
|
printer.save(dir);
|
||||||
print.set_status(100, "Writing layers completed");
|
print.set_status(initstatus + 100, "Writing layers completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include <slic3r/GUI/GUI.hpp>
|
#include <slic3r/GUI/GUI.hpp>
|
||||||
#include <slic3r/GUI/PresetBundle.hpp>
|
#include <slic3r/GUI/PresetBundle.hpp>
|
||||||
@ -230,43 +231,52 @@ void PrintController::gen_support_material(PrintObject *pobj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintController::slice()
|
void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
|
||||||
{
|
{
|
||||||
|
auto st = pri->state();
|
||||||
|
|
||||||
Slic3r::trace(3, "Starting the slicing process.");
|
Slic3r::trace(3, "Starting the slicing process.");
|
||||||
|
|
||||||
progress_indicator()->update(20u, "Generating perimeters");
|
pri->update(st+20, "Generating perimeters");
|
||||||
for(auto obj : print_->objects) make_perimeters(obj);
|
for(auto obj : print_->objects) make_perimeters(obj);
|
||||||
|
|
||||||
progress_indicator()->update(60u, "Infilling layers");
|
pri->update(st+60, "Infilling layers");
|
||||||
for(auto obj : print_->objects) infill(obj);
|
for(auto obj : print_->objects) infill(obj);
|
||||||
|
|
||||||
progress_indicator()->update(70u, "Generating support material");
|
pri->update(st+70, "Generating support material");
|
||||||
for(auto obj : print_->objects) gen_support_material(obj);
|
for(auto obj : print_->objects) gen_support_material(obj);
|
||||||
|
|
||||||
progress_indicator()->message_fmt("Weight: %.1fg, Cost: %.1f",
|
pri->message_fmt("Weight: %.1fg, Cost: %.1f",
|
||||||
print_->total_weight,
|
print_->total_weight,
|
||||||
print_->total_cost);
|
print_->total_cost);
|
||||||
|
|
||||||
progress_indicator()->state(85u);
|
pri->state(st+85);
|
||||||
|
|
||||||
|
|
||||||
progress_indicator()->update(88u, "Generating skirt");
|
pri->update(st+88, "Generating skirt");
|
||||||
make_skirt();
|
make_skirt();
|
||||||
|
|
||||||
|
|
||||||
progress_indicator()->update(90u, "Generating brim");
|
pri->update(st+90, "Generating brim");
|
||||||
make_brim();
|
make_brim();
|
||||||
|
|
||||||
progress_indicator()->update(95u, "Generating wipe tower");
|
pri->update(st+95, "Generating wipe tower");
|
||||||
make_wipe_tower();
|
make_wipe_tower();
|
||||||
|
|
||||||
progress_indicator()->update(100u, "Done");
|
pri->update(st+100, "Done");
|
||||||
|
|
||||||
// time to make some statistics..
|
// time to make some statistics..
|
||||||
|
|
||||||
Slic3r::trace(3, "Slicing process finished.");
|
Slic3r::trace(3, "Slicing process finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PrintController::slice()
|
||||||
|
{
|
||||||
|
auto pri = progress_indicator();
|
||||||
|
slice(pri);
|
||||||
|
}
|
||||||
|
|
||||||
void PrintController::slice_to_png()
|
void PrintController::slice_to_png()
|
||||||
{
|
{
|
||||||
auto exd = query_png_export_data();
|
auto exd = query_png_export_data();
|
||||||
@ -319,22 +329,22 @@ void PrintController::slice_to_png()
|
|||||||
report_issue(IssueType::WARN, ss.str(), "Warning");
|
report_issue(IssueType::WARN, ss.str(), "Warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::async(supports_asynch()? std::launch::async : std::launch::deferred,
|
// std::async(supports_asynch()? std::launch::async : std::launch::deferred,
|
||||||
[this, exd, correction]()
|
// [this, exd, correction]()
|
||||||
{
|
// {
|
||||||
progress_indicator(100, "Slicing to zipped png files...");
|
auto pri = create_progress_indicator(200, "Slicing to zipped png files...");
|
||||||
progress_indicator()->procedure_count(3);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
slice();
|
pri->update(0, "Slicing...");
|
||||||
|
slice(pri);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
report_issue(IssueType::ERR, e.what(), "Exception");
|
report_issue(IssueType::ERR, e.what(), "Exception");
|
||||||
progress_indicator()->cancel();
|
pri->cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pbak = print_->progressindicator;
|
auto pbak = print_->progressindicator;
|
||||||
print_->progressindicator = progress_indicator();
|
print_->progressindicator = pri;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
print_to<FilePrinterFormat::PNG>( *print_, exd.zippath,
|
print_to<FilePrinterFormat::PNG>( *print_, exd.zippath,
|
||||||
@ -344,7 +354,7 @@ void PrintController::slice_to_png()
|
|||||||
|
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
report_issue(IssueType::ERR, e.what(), "Exception");
|
report_issue(IssueType::ERR, e.what(), "Exception");
|
||||||
progress_indicator()->cancel();
|
pri->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(correction) { // scale the model back
|
if(correction) { // scale the model back
|
||||||
@ -360,7 +370,8 @@ void PrintController::slice_to_png()
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_->progressindicator = pbak;
|
print_->progressindicator = pbak;
|
||||||
});
|
// });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IProgressIndicator::message_fmt(
|
void IProgressIndicator::message_fmt(
|
||||||
|
@ -147,6 +147,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool supports_asynch() const;
|
bool supports_asynch() const;
|
||||||
|
|
||||||
|
void process_events();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,6 +202,8 @@ protected:
|
|||||||
// The previous export data, to pre-populate the dialog
|
// The previous export data, to pre-populate the dialog
|
||||||
PngExportData prev_expdata_;
|
PngExportData prev_expdata_;
|
||||||
|
|
||||||
|
void slice(ProgresIndicatorPtr pri);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Must be public for perl to use it
|
// Must be public for perl to use it
|
||||||
|
@ -26,6 +26,11 @@ bool AppControllerBoilerplate::supports_asynch() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppControllerBoilerplate::process_events()
|
||||||
|
{
|
||||||
|
wxSafeYield();
|
||||||
|
}
|
||||||
|
|
||||||
AppControllerBoilerplate::PathList
|
AppControllerBoilerplate::PathList
|
||||||
AppControllerBoilerplate::query_destination_paths(
|
AppControllerBoilerplate::query_destination_paths(
|
||||||
const std::string &title,
|
const std::string &title,
|
||||||
@ -95,11 +100,11 @@ namespace {
|
|||||||
class GuiProgressIndicator:
|
class GuiProgressIndicator:
|
||||||
public IProgressIndicator, public wxEvtHandler {
|
public IProgressIndicator, public wxEvtHandler {
|
||||||
|
|
||||||
std::shared_ptr<wxProgressDialog> gauge_;
|
wxProgressDialog gauge_;
|
||||||
using Base = IProgressIndicator;
|
using Base = IProgressIndicator;
|
||||||
wxString message_;
|
wxString message_;
|
||||||
int range_; wxString title_;
|
int range_; wxString title_;
|
||||||
unsigned prc_ = 0;
|
// unsigned prc_ = 0;
|
||||||
bool is_asynch_ = false;
|
bool is_asynch_ = false;
|
||||||
|
|
||||||
const int id_ = wxWindow::NewControlId();
|
const int id_ = wxWindow::NewControlId();
|
||||||
@ -107,29 +112,26 @@ class GuiProgressIndicator:
|
|||||||
// status update handler
|
// status update handler
|
||||||
void _state( wxCommandEvent& evt) {
|
void _state( wxCommandEvent& evt) {
|
||||||
unsigned st = evt.GetInt();
|
unsigned st = evt.GetInt();
|
||||||
|
message_ = evt.GetString();
|
||||||
_state(st);
|
_state(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status update implementation
|
// Status update implementation
|
||||||
void _state( unsigned st) {
|
void _state( unsigned st) {
|
||||||
if(st < max()) {
|
// if(st < max()) {
|
||||||
if(!gauge_) gauge_ = std::make_shared<wxProgressDialog>(
|
if(!gauge_.IsShown()) gauge_.ShowModal();
|
||||||
title_, message_, range_, wxTheApp->GetTopWindow(),
|
|
||||||
wxPD_APP_MODAL | wxPD_AUTO_HIDE
|
|
||||||
);
|
|
||||||
|
|
||||||
if(!gauge_->IsShown()) gauge_->ShowModal();
|
|
||||||
Base::state(st);
|
Base::state(st);
|
||||||
gauge_->Update(static_cast<int>(st), message_);
|
gauge_.Update(static_cast<int>(st), message_);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if(st == max()) {
|
// if(st == max()) {
|
||||||
prc_++;
|
// prc_++;
|
||||||
if(prc_ == Base::procedure_count()) {
|
// if(prc_ == Base::procedure_count()) {
|
||||||
gauge_.reset();
|
// //gauge_.reset();
|
||||||
prc_ = 0;
|
// gauge_.Update(static_cast<int>(st), message_);
|
||||||
}
|
// prc_ = 0;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -142,7 +144,10 @@ public:
|
|||||||
|
|
||||||
inline GuiProgressIndicator(int range, const std::string& title,
|
inline GuiProgressIndicator(int range, const std::string& title,
|
||||||
const std::string& firstmsg) :
|
const std::string& firstmsg) :
|
||||||
range_(range), message_(_(firstmsg)), title_(_(title))
|
gauge_(title, firstmsg, range, wxTheApp->GetTopWindow(),
|
||||||
|
wxPD_APP_MODAL | wxPD_AUTO_HIDE),
|
||||||
|
message_(_(firstmsg)),
|
||||||
|
range_(range), title_(_(title))
|
||||||
{
|
{
|
||||||
Base::max(static_cast<float>(range));
|
Base::max(static_cast<float>(range));
|
||||||
Base::states(static_cast<unsigned>(range));
|
Base::states(static_cast<unsigned>(range));
|
||||||
@ -158,7 +163,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void state(float val) override {
|
virtual void state(float val) override {
|
||||||
if( val >= 1.0) state(static_cast<unsigned>(val));
|
/*if( val >= 1.0) */state(static_cast<unsigned>(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
void state(unsigned st) {
|
void state(unsigned st) {
|
||||||
@ -166,6 +171,7 @@ public:
|
|||||||
if(is_asynch_) {
|
if(is_asynch_) {
|
||||||
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
||||||
evt->SetInt(st);
|
evt->SetInt(st);
|
||||||
|
evt->SetString(message_);
|
||||||
wxQueueEvent(this, evt);
|
wxQueueEvent(this, evt);
|
||||||
} else _state(st);
|
} else _state(st);
|
||||||
}
|
}
|
||||||
@ -223,7 +229,7 @@ class Wrapper: public IProgressIndicator, public wxEvtHandler {
|
|||||||
if(!gauge_->IsShown()) showProgress(true);
|
if(!gauge_->IsShown()) showProgress(true);
|
||||||
|
|
||||||
stbar_->SetStatusText(message_);
|
stbar_->SetStatusText(message_);
|
||||||
if(st == gauge_->GetRange()) {
|
if(static_cast<long>(st) == gauge_->GetRange()) {
|
||||||
gauge_->SetValue(0);
|
gauge_->SetValue(0);
|
||||||
showProgress(false);
|
showProgress(false);
|
||||||
} else {
|
} else {
|
||||||
@ -409,5 +415,4 @@ PrintController::PngExportData PrintController::query_png_export_data()
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
float state_ = .0f, max_ = 1.f, step_;
|
float state_ = .0f, max_ = 1.f, step_;
|
||||||
CancelFn cancelfunc_ = [](){};
|
CancelFn cancelfunc_ = [](){};
|
||||||
unsigned proc_count_ = 1;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -60,19 +59,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void cancel() { cancelfunc_(); }
|
virtual void cancel() { cancelfunc_(); }
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Set up how many subprocedures does the whole operation contain.
|
|
||||||
*
|
|
||||||
* This was neccesary from practical reasons. If the progress indicator is
|
|
||||||
* a dialog and we want to show the progress of a few sub operations than
|
|
||||||
* the dialog wont be closed and reopened each time a new sub operation is
|
|
||||||
* started. This is not a mandatory feature and can be ignored completely.
|
|
||||||
*/
|
|
||||||
inline void procedure_count(unsigned pc) { proc_count_ = pc; }
|
|
||||||
|
|
||||||
/// Get the current procedure count
|
|
||||||
inline unsigned procedure_count() const { return proc_count_; }
|
|
||||||
|
|
||||||
/// Convinience function to call message and status update in one function.
|
/// Convinience function to call message and status update in one function.
|
||||||
void update(float st, const std::string& msg) {
|
void update(float st, const std::string& msg) {
|
||||||
message(msg); state(st);
|
message(msg); state(st);
|
||||||
|
Loading…
Reference in New Issue
Block a user