New reliable way to see if a refresh gcode & slice previews is needed

This commit is contained in:
supermerill 2022-02-13 17:18:10 +01:00
parent f0418a9836
commit 7acc14b06e
7 changed files with 52 additions and 25 deletions

View File

@ -8,6 +8,7 @@
#include "libslic3r/CustomGCode.hpp" #include "libslic3r/CustomGCode.hpp"
#include <cstdint> #include <cstdint>
#include <ctime>
#include <array> #include <array>
#include <vector> #include <vector>
#include <string> #include <string>
@ -301,6 +302,8 @@ namespace Slic3r {
std::vector<std::string> extruder_colors; std::vector<std::string> extruder_colors;
std::vector<std::string> filament_colors; std::vector<std::string> filament_colors;
PrintEstimatedTimeStatistics time_statistics; PrintEstimatedTimeStatistics time_statistics;
// timestamp of creation, to check if it's an old or new one
std::time_t computed_timestamp = std::time(0);
#if ENABLE_GCODE_VIEWER_STATISTICS #if ENABLE_GCODE_VIEWER_STATISTICS
int64_t time{ 0 }; int64_t time{ 0 };
@ -321,6 +324,7 @@ namespace Slic3r {
extruder_colors = std::vector<std::string>(); extruder_colors = std::vector<std::string>();
extruders_count = 0; extruders_count = 0;
settings_ids.reset(); settings_ids.reset();
computed_timestamp = std::time(0);
} }
#endif // ENABLE_GCODE_VIEWER_STATISTICS #endif // ENABLE_GCODE_VIEWER_STATISTICS
}; };

View File

@ -331,6 +331,8 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
for (PrintObjectStep ostep : osteps) for (PrintObjectStep ostep : osteps)
for (PrintObject *object : m_objects) for (PrintObject *object : m_objects)
invalidated |= object->invalidate_step(ostep); invalidated |= object->invalidate_step(ostep);
if(invalidated)
m_timestamp_last_change = std::time(0);
return invalidated; return invalidated;
} }
@ -700,8 +702,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
// Do not use the ApplyStatus as we will use the max function when updating apply_status. // Do not use the ApplyStatus as we will use the max function when updating apply_status.
unsigned int apply_status = APPLY_STATUS_UNCHANGED; unsigned int apply_status = APPLY_STATUS_UNCHANGED;
auto update_apply_status = [&apply_status](bool invalidated) auto update_apply_status = [this, &apply_status](bool invalidated){
{ apply_status = std::max<unsigned int>(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED); }; apply_status = std::max<unsigned int>(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED);
if(invalidated)
this->m_timestamp_last_change = std::time(0);
};
if (! (print_diff.empty() && object_diff.empty() && region_diff.empty())) if (! (print_diff.empty() && object_diff.empty() && region_diff.empty()))
update_apply_status(false); update_apply_status(false);
@ -712,6 +717,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
if (! print_diff.empty()) if (! print_diff.empty())
update_apply_status(this->invalidate_state_by_config_options(print_diff)); update_apply_status(this->invalidate_state_by_config_options(print_diff));
// we change everything, reset the modify time
this->m_timestamp_last_change = std::time(0);
// Apply variables to placeholder parser. The placeholder parser is used by G-code export, // Apply variables to placeholder parser. The placeholder parser is used by G-code export,
// which should be stopped if print_diff is not empty. // which should be stopped if print_diff is not empty.
size_t num_extruders = m_config.nozzle_diameter.size(); size_t num_extruders = m_config.nozzle_diameter.size();
@ -1800,6 +1808,7 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
// Slicing process, running at a background thread. // Slicing process, running at a background thread.
void Print::process() void Print::process()
{ {
m_timestamp_last_change = std::time(0);
name_tbb_thread_pool_threads(); name_tbb_thread_pool_threads();
bool something_done = !is_step_done_unguarded(psBrim); bool something_done = !is_step_done_unguarded(psBrim);
BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info(); BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info();
@ -1942,6 +1951,7 @@ void Print::process()
this->finalize_first_layer_convex_hull(); this->finalize_first_layer_convex_hull();
this->set_done(psBrim); this->set_done(psBrim);
} }
m_timestamp_last_change = std::time(0);
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
//notify gui that the slicing/preview structs are ready to be drawed //notify gui that the slicing/preview structs are ready to be drawed
if (something_done) if (something_done)

View File

@ -16,6 +16,8 @@
#include "libslic3r.h" #include "libslic3r.h"
#include <ctime>
namespace Slic3r { namespace Slic3r {
class Print; class Print;
@ -478,6 +480,8 @@ public:
const PrintStatistics& print_statistics() const { return m_print_statistics; } const PrintStatistics& print_statistics() const { return m_print_statistics; }
PrintStatistics& print_statistics() { return m_print_statistics; } PrintStatistics& print_statistics() { return m_print_statistics; }
std::time_t timestamp_last_change() const { return m_timestamp_last_change; }
// Wipe tower support. // Wipe tower support.
bool has_wipe_tower() const; bool has_wipe_tower() const;
@ -549,6 +553,8 @@ private:
// Estimated print time, filament consumed. // Estimated print time, filament consumed.
PrintStatistics m_print_statistics; PrintStatistics m_print_statistics;
// tiem of last change, to see if the gui need to be updated
std::time_t m_timestamp_last_change;
// To allow GCode to set the Print's GCodeExport step status. // To allow GCode to set the Print's GCodeExport step status.
friend class GCode; friend class GCode;

View File

@ -2364,8 +2364,8 @@ static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume&
void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors) void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors)
{ {
if (m_dirty_gcode) { if (last_showned_gcode != gcode_result.computed_timestamp) {
m_dirty_gcode = false; last_showned_gcode = gcode_result.computed_timestamp;
m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized);
if (wxGetApp().is_editor()) { if (wxGetApp().is_editor()) {
@ -2401,6 +2401,14 @@ void GLCanvas3D::load_sla_preview()
} }
} }
bool GLCanvas3D::is_preview_dirty() {
const Print* print = this->fff_print();
if (print == nullptr)
return false;
return last_showned_print != print->timestamp_last_change();
}
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values) void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values)
{ {
const Print* print = this->fff_print(); const Print* print = this->fff_print();
@ -2409,8 +2417,8 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
_set_current(); _set_current();
if (m_dirty_preview || m_volumes.empty()) { if (last_showned_print != print->timestamp_last_change() || m_volumes.empty()) {
m_dirty_preview = false; last_showned_print = print->timestamp_last_change();
// Release OpenGL data before generating new data. // Release OpenGL data before generating new data.
this->reset_volumes(); this->reset_volumes();
//note: this isn't releasing all the memory in all os, can make it crash on linux for exemple. //note: this isn't releasing all the memory in all os, can make it crash on linux for exemple.

View File

@ -476,8 +476,8 @@ private:
// Screen is only refreshed from the OnIdle handler if it is dirty. // Screen is only refreshed from the OnIdle handler if it is dirty.
bool m_dirty; bool m_dirty;
bool m_dirty_preview = true; std::time_t last_showned_gcode = 0;
bool m_dirty_gcode = true; std::time_t last_showned_print = 0;
bool m_initialized; bool m_initialized;
bool m_apply_zoom_to_volumes_filter; bool m_apply_zoom_to_volumes_filter;
mutable std::vector<int> m_hover_volume_idxs; mutable std::vector<int> m_hover_volume_idxs;
@ -560,9 +560,7 @@ public:
void post_event(wxEvent &&event); void post_event(wxEvent &&event);
void set_as_dirty(); void set_as_dirty();
void set_preview_dirty() { m_dirty_preview = true; } bool is_preview_dirty();
bool is_preview_dirty() { return m_dirty_preview; }
void set_gcode_viewer_dirty() { m_dirty_gcode = true; }
void set_items_show(bool show_objects, bool show_gcode); void set_items_show(bool show_objects, bool show_gcode);
unsigned int get_volumes_count() const; unsigned int get_volumes_count() const;

View File

@ -419,7 +419,6 @@ void Preview::reload_print(bool keep_volumes)
#endif /* __linux__ */ #endif /* __linux__ */
(!keep_volumes && m_canvas->is_preview_dirty())) (!keep_volumes && m_canvas->is_preview_dirty()))
{ {
m_canvas->set_preview_dirty();
m_canvas->reset_volumes(); m_canvas->reset_volumes();
m_loaded = false; m_loaded = false;
#ifdef __linux__ #ifdef __linux__

View File

@ -3142,12 +3142,14 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
if (invalidated != Print::ApplyStatus::APPLY_STATUS_UNCHANGED && wxGetApp().app_config->get("auto_switch_preview") != "0") if (invalidated != Print::ApplyStatus::APPLY_STATUS_UNCHANGED && wxGetApp().app_config->get("auto_switch_preview") != "0")
{ {
// auto_switch_preview == 3 means "force tab change only if for gcode" // auto_switch_preview == 3 means "force tab change only if for gcode"
if(wxGetApp().app_config->get("auto_switch_preview") == "3") if (wxGetApp().app_config->get("auto_switch_preview") == "3") {
if (this->preview->can_display_gcode()) if (this->preview->can_display_gcode())
main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true); main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true);
// auto_switch_preview == 1 means "force tab change" // auto_switch_preview == 1 means "force tab change"
// auto_switch_preview == 2 (the only other one) means "force tab change only if already on a plater one" } else if (wxGetApp().app_config->get("auto_switch_preview") == "1") {
else if (wxGetApp().app_config->get("auto_switch_preview") == "1" || main_frame->selected_tab() < MainFrame::ETabType::LastPlater) { main_frame->select_tab(MainFrame::ETabType::Plater3D, true);
// auto_switch_preview == 2 means "force tab change only if already on a plater one"
} else if (wxGetApp().app_config->get("auto_switch_preview") == "2" || main_frame->selected_tab() < MainFrame::ETabType::LastPlater) {
if (this->preview->can_display_gcode()) if (this->preview->can_display_gcode())
main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true); main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true);
else if (this->preview->can_display_volume()) else if (this->preview->can_display_volume())
@ -3706,10 +3708,10 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
{ {
//update dirty flags //update dirty flags
if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::SLICING_ENDED)) //if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::SLICING_ENDED))
preview->get_canvas3d()->set_preview_dirty(); // preview->get_canvas3d()->set_preview_dirty();
if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::GCODE_ENDED)) //if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::GCODE_ENDED))
preview->get_canvas3d()->set_gcode_viewer_dirty(); // preview->get_canvas3d()->set_gcode_viewer_dirty();
if (evt.status.percent >= -1) { if (evt.status.percent >= -1) {
if (m_ui_jobs.is_any_running()) { if (m_ui_jobs.is_any_running()) {
@ -3819,8 +3821,8 @@ void Plater::priv::on_slicing_began()
{ {
clear_warnings(); clear_warnings();
notification_manager->close_notification_of_type(NotificationType::SlicingComplete); notification_manager->close_notification_of_type(NotificationType::SlicingComplete);
preview->get_canvas3d()->set_gcode_viewer_dirty(); //preview->get_canvas3d()->set_gcode_viewer_dirty();
preview->get_canvas3d()->set_preview_dirty(); //preview->get_canvas3d()->set_preview_dirty();
} }
void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, size_t oid) void Plater::priv::add_warning(const Slic3r::PrintStateBase::Warning& warning, size_t oid)
{ {
@ -5103,8 +5105,8 @@ void Plater::load_gcode(const wxString& filename)
p->gcode_result = std::move(processor.extract_result()); p->gcode_result = std::move(processor.extract_result());
// show results // show results
p->preview->get_canvas3d()->set_preview_dirty(); //p->preview->get_canvas3d()->set_preview_dirty();
p->preview->get_canvas3d()->set_gcode_viewer_dirty(); //p->preview->get_canvas3d()->set_gcode_viewer_dirty();
p->preview->reload_print(false); p->preview->reload_print(false);
p->preview->get_canvas3d()->zoom_to_gcode(); p->preview->get_canvas3d()->zoom_to_gcode();