diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 191f7756a..0015ae753 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -8,6 +8,7 @@ #include "libslic3r/CustomGCode.hpp" #include +#include #include #include #include @@ -301,6 +302,8 @@ namespace Slic3r { std::vector extruder_colors; std::vector filament_colors; 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 int64_t time{ 0 }; @@ -321,6 +324,7 @@ namespace Slic3r { extruder_colors = std::vector(); extruders_count = 0; settings_ids.reset(); + computed_timestamp = std::time(0); } #endif // ENABLE_GCODE_VIEWER_STATISTICS }; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index b6ebceaa1..a22307217 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -331,6 +331,8 @@ bool Print::invalidate_state_by_config_options(const std::vectorinvalidate_step(ostep); + if(invalidated) + m_timestamp_last_change = std::time(0); 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. unsigned int apply_status = APPLY_STATUS_UNCHANGED; - auto update_apply_status = [&apply_status](bool invalidated) - { apply_status = std::max(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED); }; + auto update_apply_status = [this, &apply_status](bool invalidated){ + apply_status = std::max(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())) update_apply_status(false); @@ -712,6 +717,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ if (! print_diff.empty()) 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, // which should be stopped if print_diff is not empty. 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. void Print::process() { + m_timestamp_last_change = std::time(0); name_tbb_thread_pool_threads(); bool something_done = !is_step_done_unguarded(psBrim); 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->set_done(psBrim); } + m_timestamp_last_change = std::time(0); BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); //notify gui that the slicing/preview structs are ready to be drawed if (something_done) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 1345ceaab..3ddcbd5a0 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -16,6 +16,8 @@ #include "libslic3r.h" +#include + namespace Slic3r { class Print; @@ -478,6 +480,8 @@ public: const PrintStatistics& print_statistics() const { 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. bool has_wipe_tower() const; @@ -549,6 +553,8 @@ private: // Estimated print time, filament consumed. 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. friend class GCode; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 84caae8c9..ae6c72ee2 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -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& str_tool_colors) { - if (m_dirty_gcode) { - m_dirty_gcode = false; + if (last_showned_gcode != gcode_result.computed_timestamp) { + last_showned_gcode = gcode_result.computed_timestamp; m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); 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& str_tool_colors, const std::vector& color_print_values) { const Print* print = this->fff_print(); @@ -2409,8 +2417,8 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c _set_current(); - if (m_dirty_preview || m_volumes.empty()) { - m_dirty_preview = false; + if (last_showned_print != print->timestamp_last_change() || m_volumes.empty()) { + last_showned_print = print->timestamp_last_change(); // Release OpenGL data before generating new data. this->reset_volumes(); //note: this isn't releasing all the memory in all os, can make it crash on linux for exemple. diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 97a3aa06b..d940bb9f4 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -476,8 +476,8 @@ private: // Screen is only refreshed from the OnIdle handler if it is dirty. bool m_dirty; - bool m_dirty_preview = true; - bool m_dirty_gcode = true; + std::time_t last_showned_gcode = 0; + std::time_t last_showned_print = 0; bool m_initialized; bool m_apply_zoom_to_volumes_filter; mutable std::vector m_hover_volume_idxs; @@ -560,9 +560,7 @@ public: void post_event(wxEvent &&event); void set_as_dirty(); - void set_preview_dirty() { m_dirty_preview = true; } - bool is_preview_dirty() { return m_dirty_preview; } - void set_gcode_viewer_dirty() { m_dirty_gcode = true; } + bool is_preview_dirty(); void set_items_show(bool show_objects, bool show_gcode); unsigned int get_volumes_count() const; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 65008171f..ab16a0cc4 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -419,7 +419,6 @@ void Preview::reload_print(bool keep_volumes) #endif /* __linux__ */ (!keep_volumes && m_canvas->is_preview_dirty())) { - m_canvas->set_preview_dirty(); m_canvas->reset_volumes(); m_loaded = false; #ifdef __linux__ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 97940df2d..5a9c4599f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -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") { // auto_switch_preview == 3 means "force tab change only if for gcode" - if(wxGetApp().app_config->get("auto_switch_preview") == "3") - if(this->preview->can_display_gcode()) + if (wxGetApp().app_config->get("auto_switch_preview") == "3") { + if (this->preview->can_display_gcode()) main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true); - // 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" || main_frame->selected_tab() < MainFrame::ETabType::LastPlater) { + // auto_switch_preview == 1 means "force tab change" + } else if (wxGetApp().app_config->get("auto_switch_preview") == "1") { + 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()) main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true); 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) { //update dirty flags - if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::SLICING_ENDED)) - preview->get_canvas3d()->set_preview_dirty(); - if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::GCODE_ENDED)) - preview->get_canvas3d()->set_gcode_viewer_dirty(); + //if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::SLICING_ENDED)) + // preview->get_canvas3d()->set_preview_dirty(); + //if (0 != (evt.status.flags & Slic3r::PrintBase::SlicingStatus::FlagBits::GCODE_ENDED)) + // preview->get_canvas3d()->set_gcode_viewer_dirty(); if (evt.status.percent >= -1) { if (m_ui_jobs.is_any_running()) { @@ -3819,8 +3821,8 @@ void Plater::priv::on_slicing_began() { clear_warnings(); notification_manager->close_notification_of_type(NotificationType::SlicingComplete); - preview->get_canvas3d()->set_gcode_viewer_dirty(); - preview->get_canvas3d()->set_preview_dirty(); + //preview->get_canvas3d()->set_gcode_viewer_dirty(); + //preview->get_canvas3d()->set_preview_dirty(); } 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()); // show results - p->preview->get_canvas3d()->set_preview_dirty(); - p->preview->get_canvas3d()->set_gcode_viewer_dirty(); + //p->preview->get_canvas3d()->set_preview_dirty(); + //p->preview->get_canvas3d()->set_gcode_viewer_dirty(); p->preview->reload_print(false); p->preview->get_canvas3d()->zoom_to_gcode();