From 6741b9ba254c7ce309c503e55c79224b9dd3b644 Mon Sep 17 00:00:00 2001 From: supermerill Date: Sat, 4 Sep 2021 22:09:19 +0200 Subject: [PATCH] Improved progress message --- src/PrusaSlicer.cpp | 4 ++-- src/libslic3r/GCode.cpp | 9 +++++++++ src/libslic3r/GCode.hpp | 4 ++++ src/libslic3r/PrintBase.hpp | 17 +++++++++++----- src/libslic3r/PrintObject.cpp | 38 +++++++++++++++++++++++++++++++++-- src/slic3r/GUI/Plater.cpp | 19 +++++++++++++++++- 6 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 24ba4a1b2..a02876484 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -471,8 +471,8 @@ int CLI::run(int argc, char **argv) sla_print.set_status_callback( [](const PrintBase::SlicingStatus& s) { - if(s.percent >= 0) // FIXME: is this sufficient? - printf("%3d%s %s\n", s.percent, "% =>", s.text.c_str()); + if(s.percent >= 0 && s.args.empty()) // FIXME: is this sufficient? + printf("%3d%s %s\n", s.percent, "% =>", s.main_text.c_str()); }); PrintBase *print = (printer_technology == ptFFF) ? static_cast(&fff_print) : static_cast(&sla_print); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index b48d9fb43..dc167fc09 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1087,6 +1087,8 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu { PROFILE_FUNC(); + m_last_status_update = std::chrono::system_clock::now(); + // modifies m_silent_time_estimator_enabled DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled); @@ -2712,6 +2714,13 @@ void GCode::process_layer( _write(file, gcode); BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << log_memory_info(); + + + std::chrono::time_point end_export_layer = std::chrono::system_clock::now(); + if ((static_cast>(end_export_layer - m_last_status_update)).count() > 0.2) { + m_last_status_update = std::chrono::system_clock::now(); + print.set_status(int((layer.id() * 100) / layer_count()), std::string(L("Generating G-code layer %s / %s")), std::vector{ std::to_string(layer.id()), std::to_string(layer_count()) }, PrintBase::SlicingStatus::DEFAULT); + } } void GCode::apply_print_config(const PrintConfig &print_config) diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 016fc4524..a5bfb881e 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef HAS_PRESSURE_EQUALIZER #include "GCode/PressureEqualizer.hpp" @@ -409,6 +410,9 @@ private: bool m_silent_time_estimator_enabled; + //for gui status update + std::chrono::time_point m_last_status_update; + // Processor GCodeProcessor m_processor; diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 5c0a1ebc9..aecb43089 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -389,13 +389,16 @@ public: virtual void finalize() {} struct SlicingStatus { - SlicingStatus(int percent, const std::string &text, unsigned int flags = 0) : percent(percent), text(text), flags(flags) {} + SlicingStatus(int percent, const std::string& text, unsigned int flags = 0) : percent(percent), main_text(text), flags(flags) {} + SlicingStatus(int percent, const std::string& text, const std::vector& args, unsigned int flags = 0) + : percent(percent), main_text(text), args(args), flags(flags) {} SlicingStatus(const PrintBase &print, int warning_step) : flags(UPDATE_PRINT_STEP_WARNINGS), warning_object_id(print.id()), warning_step(warning_step) {} SlicingStatus(const PrintObjectBase &print_object, int warning_step) : flags(UPDATE_PRINT_OBJECT_STEP_WARNINGS), warning_object_id(print_object.id()), warning_step(warning_step) {} - int percent { -1 }; - std::string text; + int percent { -1 }; + std::string main_text; + std::vector args; // Bitmap of flags. enum FlagBits { DEFAULT = 0, @@ -422,8 +425,12 @@ public: // Register a custom status callback. void set_status_callback(status_callback_type cb) { m_status_callback = cb; } // Calls a registered callback to update the status, or print out the default message. - void set_status(int percent, const std::string &message, unsigned int flags = SlicingStatus::DEFAULT) { - if (m_status_callback) m_status_callback(SlicingStatus(percent, message, flags)); + void set_status(int percent, const std::string& message, unsigned int flags = SlicingStatus::DEFAULT) const { + if (m_status_callback) m_status_callback(SlicingStatus(percent, message, flags)); + else printf("%d => %s\n", percent, message.c_str()); + } + void set_status(int percent, const std::string& message, const std::vector& args, unsigned int flags = SlicingStatus::DEFAULT) const { + if (m_status_callback) m_status_callback(SlicingStatus(percent, message, args, flags)); else printf("%d => %s\n", percent, message.c_str()); } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index ce9b92c9d..d32d44fc4 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -303,6 +303,11 @@ namespace Slic3r { m_typed_slices = false; } + // atomic counter for gui progress + std::atomic atomic_count{ 0 }; + int nb_layers_update = std::max(1, (int)m_layers.size() / 20); + std::chrono::time_point last_update = std::chrono::system_clock::now(); + // compare each layer to the one below, and mark those slices needing // one additional inner perimeter, like the top of domed objects- @@ -376,10 +381,22 @@ namespace Slic3r { BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), - [this](const tbb::blocked_range& range) { + [this, &atomic_count, &last_update, nb_layers_update](const tbb::blocked_range& range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { + std::chrono::time_point start_make_perimeter = std::chrono::system_clock::now(); m_print->throw_if_canceled(); m_layers[layer_idx]->make_perimeters(); + + // updating progress + int nb_layers_done = (++atomic_count); + std::chrono::time_point end_make_perimeter = std::chrono::system_clock::now(); + if (nb_layers_done % nb_layers_update == 0 || (static_cast>(end_make_perimeter - start_make_perimeter)).count() > 5) { + if ((static_cast>(end_make_perimeter - last_update)).count() > 0.2) { + // note: i don't care if a thread erase last_update in-between here + last_update = std::chrono::system_clock::now(); + m_print->set_status( int((nb_layers_done * 100) / m_layers.size()), L("Generating perimeters: layer %s / %s"), { std::to_string(nb_layers_done), std::to_string(m_layers.size()) }); + } + } } } ); @@ -548,13 +565,30 @@ namespace Slic3r { if (this->set_started(posInfill)) { auto [adaptive_fill_octree, support_fill_octree] = this->prepare_adaptive_infill_data(); + // atomic counter for gui progress + std::atomic atomic_count{ 0 }; + int nb_layers_update = std::max(1, (int)m_layers.size() / 20); + std::chrono::time_point last_update = std::chrono::system_clock::now(); + BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - start"; tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), - [this, &adaptive_fill_octree = adaptive_fill_octree, &support_fill_octree = support_fill_octree](const tbb::blocked_range& range) { + [this, &adaptive_fill_octree = adaptive_fill_octree, &support_fill_octree = support_fill_octree, &atomic_count , &last_update, nb_layers_update](const tbb::blocked_range& range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { + std::chrono::time_point start_make_fill = std::chrono::system_clock::now(); m_print->throw_if_canceled(); m_layers[layer_idx]->make_fills(adaptive_fill_octree.get(), support_fill_octree.get()); + + // updating progress + int nb_layers_done = (++atomic_count); + std::chrono::time_point end_make_fill = std::chrono::system_clock::now(); + if (nb_layers_done % nb_layers_update == 0 || (static_cast>(end_make_fill - start_make_fill)).count() > 5) { + if ((static_cast>(end_make_fill - last_update)).count() > 0.2) { + // note: i don't care if a thread erase last_update in-between here + last_update = std::chrono::system_clock::now(); + m_print->set_status( int((nb_layers_done * 100) / m_layers.size()), L("Infilling layer %s / %s"), { std::to_string(nb_layers_done), std::to_string(m_layers.size()) }); + } + } } } ); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 35abd56e4..bb66a34d6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3675,7 +3675,24 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } this->statusbar()->set_progress(evt.status.percent); - this->statusbar()->set_status_text(_(evt.status.text) + wxString::FromUTF8("…")); + if (evt.status.args.empty()) { + this->statusbar()->set_status_text(_(evt.status.main_text) + wxString::FromUTF8("…")); + } else { + std::vector arg_lst; + for (std::string str : evt.status.args) + arg_lst.push_back(_(str)); + //FIXME use var-args list + if (arg_lst.size() == 1) + this->statusbar()->set_status_text(wxString::Format(_(evt.status.main_text), arg_lst[0])); + else if (arg_lst.size() == 2) + this->statusbar()->set_status_text(wxString::Format(_(evt.status.main_text), arg_lst[0], arg_lst[1])); + else if (arg_lst.size() == 3) + this->statusbar()->set_status_text(wxString::Format(_(evt.status.main_text), arg_lst[0], arg_lst[1], arg_lst[2])); + else if (arg_lst.size() == 4) + this->statusbar()->set_status_text(wxString::Format(_(evt.status.main_text), arg_lst[0], arg_lst[1], arg_lst[2], arg_lst[3])); + else + this->statusbar()->set_status_text(wxString::Format(_(evt.status.main_text), arg_lst[0], arg_lst[1], arg_lst[2], arg_lst[3], arg_lst[4])); + } //notification_manager->set_progress_bar_percentage("Slicing progress", (float)evt.status.percent / 100.0f); } if (evt.status.flags & (PrintBase::SlicingStatus::RELOAD_SCENE | PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS)) {