From 4f27f6c6dc792e3c137cb614ebf618d35d75cd71 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 2 Jul 2018 14:50:54 +0200 Subject: [PATCH] Fixing crash on linux. Exporting png in the UI thread. --- xs/src/libslic3r/PrintExport.hpp | 17 ++++++---- xs/src/slic3r/AppController.cpp | 51 +++++++++++++++++----------- xs/src/slic3r/AppController.hpp | 4 +++ xs/src/slic3r/AppControllerWx.cpp | 49 ++++++++++++++------------ xs/src/slic3r/IProgressIndicator.hpp | 14 -------- 5 files changed, 72 insertions(+), 63 deletions(-) diff --git a/xs/src/libslic3r/PrintExport.hpp b/xs/src/libslic3r/PrintExport.hpp index 1b5784bee..bf0907cd8 100644 --- a/xs/src/libslic3r/PrintExport.hpp +++ b/xs/src/libslic3r/PrintExport.hpp @@ -289,16 +289,19 @@ void print_to(Print& print, int st_prev = 0; const std::string jobdesc = "Rasterizing and compressing sliced layers"; - print.set_status(0, jobdesc); tbb::spin_mutex m; std::vector keys; keys.reserve(layers.size()); 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 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]]; @@ -345,10 +348,10 @@ void print_to(Print& print, printer.finishLayer(layer_id); // Finish the layer for later saving it. - auto st = static_cast(layer_id*100.0/layers.size()); + auto st = static_cast(layer_id*80.0/layers.size()); m.lock(); if( st - st_prev > 10) { - print.set_status(st, jobdesc); + print.set_status(initstatus + st, jobdesc); st_prev = st; } m.unlock(); @@ -364,12 +367,12 @@ void print_to(Print& print, // Sequential version (for testing) // 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. - print.set_status(0, "Writing layers to disk"); + print.set_status(initstatus + 90, "Writing layers to disk"); printer.save(dir); - print.set_status(100, "Writing layers completed"); + print.set_status(initstatus + 100, "Writing layers completed"); } } diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp index ca1164819..6b925c714 100644 --- a/xs/src/slic3r/AppController.cpp +++ b/xs/src/slic3r/AppController.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -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."); - progress_indicator()->update(20u, "Generating perimeters"); + pri->update(st+20, "Generating perimeters"); 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); - progress_indicator()->update(70u, "Generating support material"); + pri->update(st+70, "Generating support material"); 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_cost); - progress_indicator()->state(85u); + pri->state(st+85); - progress_indicator()->update(88u, "Generating skirt"); + pri->update(st+88, "Generating skirt"); make_skirt(); - progress_indicator()->update(90u, "Generating brim"); + pri->update(st+90, "Generating brim"); make_brim(); - progress_indicator()->update(95u, "Generating wipe tower"); + pri->update(st+95, "Generating wipe tower"); make_wipe_tower(); - progress_indicator()->update(100u, "Done"); + pri->update(st+100, "Done"); // time to make some statistics.. Slic3r::trace(3, "Slicing process finished."); } + +void PrintController::slice() +{ + auto pri = progress_indicator(); + slice(pri); +} + void PrintController::slice_to_png() { auto exd = query_png_export_data(); @@ -319,22 +329,22 @@ void PrintController::slice_to_png() report_issue(IssueType::WARN, ss.str(), "Warning"); } - std::async(supports_asynch()? std::launch::async : std::launch::deferred, - [this, exd, correction]() - { - progress_indicator(100, "Slicing to zipped png files..."); - progress_indicator()->procedure_count(3); +// std::async(supports_asynch()? std::launch::async : std::launch::deferred, +// [this, exd, correction]() +// { + auto pri = create_progress_indicator(200, "Slicing to zipped png files..."); try { - slice(); + pri->update(0, "Slicing..."); + slice(pri); } catch (std::exception& e) { report_issue(IssueType::ERR, e.what(), "Exception"); - progress_indicator()->cancel(); + pri->cancel(); return; } auto pbak = print_->progressindicator; - print_->progressindicator = progress_indicator(); + print_->progressindicator = pri; try { print_to( *print_, exd.zippath, @@ -344,7 +354,7 @@ void PrintController::slice_to_png() } catch (std::exception& e) { report_issue(IssueType::ERR, e.what(), "Exception"); - progress_indicator()->cancel(); + pri->cancel(); } if(correction) { // scale the model back @@ -360,7 +370,8 @@ void PrintController::slice_to_png() } print_->progressindicator = pbak; - }); +// }); + } void IProgressIndicator::message_fmt( diff --git a/xs/src/slic3r/AppController.hpp b/xs/src/slic3r/AppController.hpp index 440a7e171..39e02a1a0 100644 --- a/xs/src/slic3r/AppController.hpp +++ b/xs/src/slic3r/AppController.hpp @@ -147,6 +147,8 @@ public: */ bool supports_asynch() const; + void process_events(); + protected: /** @@ -200,6 +202,8 @@ protected: // The previous export data, to pre-populate the dialog PngExportData prev_expdata_; + void slice(ProgresIndicatorPtr pri); + public: // Must be public for perl to use it diff --git a/xs/src/slic3r/AppControllerWx.cpp b/xs/src/slic3r/AppControllerWx.cpp index 1d938ebe0..2d3dc0fd3 100644 --- a/xs/src/slic3r/AppControllerWx.cpp +++ b/xs/src/slic3r/AppControllerWx.cpp @@ -26,6 +26,11 @@ bool AppControllerBoilerplate::supports_asynch() const return true; } +void AppControllerBoilerplate::process_events() +{ + wxSafeYield(); +} + AppControllerBoilerplate::PathList AppControllerBoilerplate::query_destination_paths( const std::string &title, @@ -95,11 +100,11 @@ namespace { class GuiProgressIndicator: public IProgressIndicator, public wxEvtHandler { - std::shared_ptr gauge_; + wxProgressDialog gauge_; using Base = IProgressIndicator; wxString message_; int range_; wxString title_; - unsigned prc_ = 0; +// unsigned prc_ = 0; bool is_asynch_ = false; const int id_ = wxWindow::NewControlId(); @@ -107,29 +112,26 @@ class GuiProgressIndicator: // status update handler void _state( wxCommandEvent& evt) { unsigned st = evt.GetInt(); + message_ = evt.GetString(); _state(st); } // Status update implementation void _state( unsigned st) { - if(st < max()) { - if(!gauge_) gauge_ = std::make_shared( - title_, message_, range_, wxTheApp->GetTopWindow(), - wxPD_APP_MODAL | wxPD_AUTO_HIDE - ); - - if(!gauge_->IsShown()) gauge_->ShowModal(); +// if(st < max()) { + if(!gauge_.IsShown()) gauge_.ShowModal(); Base::state(st); - gauge_->Update(static_cast(st), message_); - } + gauge_.Update(static_cast(st), message_); +// } - if(st == max()) { - prc_++; - if(prc_ == Base::procedure_count()) { - gauge_.reset(); - prc_ = 0; - } - } +// if(st == max()) { +// prc_++; +// if(prc_ == Base::procedure_count()) { +// //gauge_.reset(); +// gauge_.Update(static_cast(st), message_); +// prc_ = 0; +// } +// } } public: @@ -142,7 +144,10 @@ public: inline GuiProgressIndicator(int range, const std::string& title, 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(range)); Base::states(static_cast(range)); @@ -158,7 +163,7 @@ public: } virtual void state(float val) override { - if( val >= 1.0) state(static_cast(val)); + /*if( val >= 1.0) */state(static_cast(val)); } void state(unsigned st) { @@ -166,6 +171,7 @@ public: if(is_asynch_) { auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_); evt->SetInt(st); + evt->SetString(message_); wxQueueEvent(this, evt); } else _state(st); } @@ -223,7 +229,7 @@ class Wrapper: public IProgressIndicator, public wxEvtHandler { if(!gauge_->IsShown()) showProgress(true); stbar_->SetStatusText(message_); - if(st == gauge_->GetRange()) { + if(static_cast(st) == gauge_->GetRange()) { gauge_->SetValue(0); showProgress(false); } else { @@ -409,5 +415,4 @@ PrintController::PngExportData PrintController::query_png_export_data() return ret; } - } diff --git a/xs/src/slic3r/IProgressIndicator.hpp b/xs/src/slic3r/IProgressIndicator.hpp index 73296697f..ee68b3d2b 100644 --- a/xs/src/slic3r/IProgressIndicator.hpp +++ b/xs/src/slic3r/IProgressIndicator.hpp @@ -16,7 +16,6 @@ public: private: float state_ = .0f, max_ = 1.f, step_; CancelFn cancelfunc_ = [](){}; - unsigned proc_count_ = 1; public: @@ -60,19 +59,6 @@ public: */ 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. void update(float st, const std::string& msg) { message(msg); state(st);