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 <cstdint>
#include <ctime>
#include <array>
#include <vector>
#include <string>
@ -301,6 +302,8 @@ namespace Slic3r {
std::vector<std::string> extruder_colors;
std::vector<std::string> 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<std::string>();
extruders_count = 0;
settings_ids.reset();
computed_timestamp = std::time(0);
}
#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 (PrintObject *object : m_objects)
invalidated |= object->invalidate_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<unsigned int>(apply_status, invalidated ? APPLY_STATUS_INVALIDATED : APPLY_STATUS_CHANGED); };
auto update_apply_status = [this, &apply_status](bool invalidated){
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()))
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)

View File

@ -16,6 +16,8 @@
#include "libslic3r.h"
#include <ctime>
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;

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)
{
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<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values)
{
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();
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.

View File

@ -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<int> 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;

View File

@ -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__

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")
{
// 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();