Fix bloating of history with live preview

This commit is contained in:
Filip Sykala 2021-10-19 16:15:27 +02:00
parent 76cbb7c17e
commit 79dd007ec7
2 changed files with 60 additions and 12 deletions

View File

@ -294,6 +294,7 @@ void GLGizmoSimplify::live_preview() {
// wait until cancel // wait until cancel
if (m_worker.joinable()) { if (m_worker.joinable()) {
m_state = State::canceling; m_state = State::canceling;
m_dealy_process_cv.notify_one();
m_worker.join(); m_worker.join();
} }
} }
@ -304,20 +305,38 @@ void GLGizmoSimplify::live_preview() {
void GLGizmoSimplify::process() void GLGizmoSimplify::process()
{ {
class SimplifyCanceledException : public std::exception { if (m_volume == nullptr) return;
public: if (m_volume->mesh().its.indices.empty()) return;
const char* what() const throw() { return L("Model simplification has been canceled"); } size_t count_triangles = m_volume->mesh().its.indices.size();
}; if (m_configuration.use_count &&
m_configuration.wanted_count >= count_triangles)
return;
if (!m_original_its.has_value()) // when not store original volume store it for cancelation
if (!m_original_its.has_value()) {
m_original_its = m_volume->mesh().its; // copy m_original_its = m_volume->mesh().its; // copy
auto plater = wxGetApp().plater(); // store previous state
plater->take_snapshot(_L("Simplify ") + m_volume->name); auto plater = wxGetApp().plater();
plater->clear_before_change_mesh(m_obj_index); plater->take_snapshot(_L("Simplify ") + m_volume->name);
plater->clear_before_change_mesh(m_obj_index);
}
m_progress = 0; m_progress = 0;
if (m_worker.joinable()) m_worker.join(); if (m_worker.joinable()) m_worker.join();
m_worker = std::thread([this]() { m_worker = std::thread([this]() {
{// delay before process
std::unique_lock<std::mutex> lk(m_state_mutex);
auto is_modify = [this]() { return m_state == State::canceling; };
if (m_dealy_process_cv.wait_for(lk, m_gui_cfg->prcess_delay, is_modify)) {
// exist modification
m_state = State::settings;
request_rerender();
return;
}
}
// store original triangles // store original triangles
uint32_t triangle_count = (m_configuration.use_count) ? m_configuration.wanted_count : 0; uint32_t triangle_count = (m_configuration.use_count) ? m_configuration.wanted_count : 0;
float max_error = (!m_configuration.use_count) ? m_configuration.max_error : std::numeric_limits<float>::max(); float max_error = (!m_configuration.use_count) ? m_configuration.max_error : std::numeric_limits<float>::max();
@ -357,6 +376,7 @@ void GLGizmoSimplify::process()
} }
void GLGizmoSimplify::set_its(indexed_triangle_set &its) { void GLGizmoSimplify::set_its(indexed_triangle_set &its) {
if (m_volume == nullptr) return; // could appear after process
m_volume->set_mesh(its); m_volume->set_mesh(its);
m_volume->calculate_convex_hull(); m_volume->calculate_convex_hull();
m_volume->set_new_unique_id(); m_volume->set_new_unique_id();

View File

@ -7,6 +7,9 @@
#include "GLGizmoPainterBase.hpp" // for render wireframe #include "GLGizmoPainterBase.hpp" // for render wireframe
#include "admesh/stl.h" // indexed_triangle_set #include "admesh/stl.h" // indexed_triangle_set
#include <thread> #include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <optional> #include <optional>
#include <atomic> #include <atomic>
@ -47,6 +50,7 @@ private:
void set_its(indexed_triangle_set &its); void set_its(indexed_triangle_set &its);
void create_gui_cfg(); void create_gui_cfg();
void request_rerender(); void request_rerender();
// move to global functions // move to global functions
static ModelVolume *get_volume(const Selection &selection, Model &model); static ModelVolume *get_volume(const Selection &selection, Model &model);
static const ModelVolume *get_volume(const GLVolume::CompositeID &cid, const Model &model); static const ModelVolume *get_volume(const GLVolume::CompositeID &cid, const Model &model);
@ -65,7 +69,11 @@ private:
bool m_show_wireframe; bool m_show_wireframe;
volatile bool m_need_reload; // after simplify, glReload must be on main thread volatile bool m_need_reload; // after simplify, glReload must be on main thread
std::thread m_worker; std::thread m_worker;
// wait before process
std::mutex m_state_mutex;
std::condition_variable m_dealy_process_cv;
enum class State { enum class State {
settings, settings,
@ -87,8 +95,14 @@ private:
void fix_count_by_ratio(size_t triangle_count) void fix_count_by_ratio(size_t triangle_count)
{ {
wanted_count = static_cast<uint32_t>( if (decimate_ratio <= 0.f) {
std::round(triangle_count * (100.f-decimate_ratio) / 100.f)); wanted_count = static_cast<uint32_t>(triangle_count);
return;
} else if (decimate_ratio >= 1.f) {
wanted_count = 0;
return;
}
wanted_count = static_cast<uint32_t>(std::round(triangle_count * (100.f-decimate_ratio) / 100.f));
} }
} m_configuration; } m_configuration;
@ -106,6 +120,10 @@ private:
// trunc model name when longer // trunc model name when longer
size_t max_char_in_name = 30; size_t max_char_in_name = 30;
// to prevent freezing when move in gui
// delay before process in [ms]
std::chrono::duration<long int, std::milli> prcess_delay = std::chrono::milliseconds(250);
}; };
std::optional<GuiCfg> m_gui_cfg; std::optional<GuiCfg> m_gui_cfg;
@ -122,6 +140,16 @@ private:
void free_gpu(); void free_gpu();
GLuint m_wireframe_VBO_id, m_wireframe_IBO_id; GLuint m_wireframe_VBO_id, m_wireframe_IBO_id;
size_t m_wireframe_IBO_size; size_t m_wireframe_IBO_size;
// cancel exception
class SimplifyCanceledException: public std::exception
{
public:
const char *what() const throw()
{
return L("Model simplification has been canceled");
}
};
}; };
} // namespace GUI } // namespace GUI