Shared data packed in a struct
This commit is contained in:
parent
ba56a79795
commit
6661967f9f
2 changed files with 55 additions and 78 deletions
|
@ -16,10 +16,9 @@ GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D & parent,
|
||||||
const std::string &icon_filename,
|
const std::string &icon_filename,
|
||||||
unsigned int sprite_id)
|
unsigned int sprite_id)
|
||||||
: GLGizmoBase(parent, icon_filename, -1)
|
: GLGizmoBase(parent, icon_filename, -1)
|
||||||
, m_state(State::settings)
|
, m_state({ State::settings, 0 })
|
||||||
, m_is_valid_result(false)
|
, m_is_valid_result(false)
|
||||||
, m_exist_preview(false)
|
, m_exist_preview(false)
|
||||||
, m_progress(0)
|
|
||||||
, m_volume(nullptr)
|
, m_volume(nullptr)
|
||||||
, m_obj_index(0)
|
, m_obj_index(0)
|
||||||
, m_need_reload(false)
|
, m_need_reload(false)
|
||||||
|
@ -34,16 +33,16 @@ GLGizmoSimplify::GLGizmoSimplify(GLCanvas3D & parent,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GLGizmoSimplify::~GLGizmoSimplify() {
|
GLGizmoSimplify::~GLGizmoSimplify() {
|
||||||
m_state = State::canceling;
|
m_state.status = State::canceling;
|
||||||
if (m_worker.joinable()) m_worker.join();
|
if (m_worker.joinable()) m_worker.join();
|
||||||
m_glmodel.reset();
|
m_glmodel.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoSimplify::on_esc_key_down() {
|
bool GLGizmoSimplify::on_esc_key_down() {
|
||||||
if (m_state == State::settings || m_state == State::canceling)
|
if (m_state.status == State::settings || m_state.status == State::canceling)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_state = State::canceling;
|
m_state.status = State::canceling;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,17 +110,17 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||||
int obj_index = selection.get_object_idx();
|
int obj_index = selection.get_object_idx();
|
||||||
ModelVolume *act_volume = get_volume(selection, wxGetApp().plater()->model());
|
ModelVolume *act_volume = get_volume(selection, wxGetApp().plater()->model());
|
||||||
if (act_volume == nullptr) {
|
if (act_volume == nullptr) {
|
||||||
switch (m_state) {
|
switch (m_state.status) {
|
||||||
case State::settings: close(); break;
|
case State::settings: close(); break;
|
||||||
case State::canceling: break;
|
case State::canceling: break;
|
||||||
default: m_state = State::canceling;
|
default: m_state.status = State::canceling;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check selection of new volume
|
// Check selection of new volume
|
||||||
// Do not reselect object when processing
|
// Do not reselect object when processing
|
||||||
if (act_volume != m_volume && m_state == State::settings) {
|
if (act_volume != m_volume && m_state.status == State::settings) {
|
||||||
bool change_window_position = (m_volume == nullptr);
|
bool change_window_position = (m_volume == nullptr);
|
||||||
// select different model
|
// select different model
|
||||||
if (m_volume != nullptr && m_original_its.has_value()) {
|
if (m_volume != nullptr && m_original_its.has_value()) {
|
||||||
|
@ -264,18 +263,18 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||||
|
|
||||||
ImGui::Checkbox(_u8L("Show wireframe").c_str(), &m_show_wireframe);
|
ImGui::Checkbox(_u8L("Show wireframe").c_str(), &m_show_wireframe);
|
||||||
|
|
||||||
bool is_canceling = m_state == State::canceling;
|
bool is_canceling = m_state.status == State::canceling;
|
||||||
m_imgui->disabled_begin(is_canceling);
|
m_imgui->disabled_begin(is_canceling);
|
||||||
if (m_imgui->button(_L("Cancel"))) {
|
if (m_imgui->button(_L("Cancel"))) {
|
||||||
if (m_state == State::settings) {
|
if (m_state.status == State::settings) {
|
||||||
if (m_original_its.has_value()) {
|
if (m_original_its.has_value()) {
|
||||||
set_its(*m_original_its);
|
set_its(*m_original_its);
|
||||||
m_state = State::close_on_end;
|
m_state.status = State::close_on_end;
|
||||||
} else {
|
} else {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_state = State::canceling;
|
m_state.status = State::canceling;
|
||||||
}
|
}
|
||||||
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_canceling)
|
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && is_canceling)
|
||||||
ImGui::SetTooltip("%s", _u8L("Operation already canceling. Please wait few seconds.").c_str());
|
ImGui::SetTooltip("%s", _u8L("Operation already canceling. Please wait few seconds.").c_str());
|
||||||
|
@ -283,11 +282,11 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
bool is_processing = m_state != State::settings;
|
bool is_processing = m_state.status != State::settings;
|
||||||
m_imgui->disabled_begin(is_processing);
|
m_imgui->disabled_begin(is_processing);
|
||||||
if (m_imgui->button(_L("Apply"))) {
|
if (m_imgui->button(_L("Apply"))) {
|
||||||
if (!m_is_valid_result) {
|
if (!m_is_valid_result) {
|
||||||
m_state = State::close_on_end;
|
m_state.status = State::close_on_end;
|
||||||
process();
|
process();
|
||||||
} else if (m_exist_preview) {
|
} else if (m_exist_preview) {
|
||||||
// use preview and close
|
// use preview and close
|
||||||
|
@ -304,20 +303,18 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
||||||
// draw progress bar
|
// draw progress bar
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int progress = m_progress;
|
sprintf(buf, L("Process %d / 100"), m_state.progress);
|
||||||
sprintf(buf, L("Process %d / 100"), progress);
|
ImGui::ProgressBar(m_state.progress / 100., ImVec2(m_gui_cfg->input_width, 0.f), buf);
|
||||||
ImGui::ProgressBar(progress / 100., ImVec2(m_gui_cfg->input_width, 0.f), buf);
|
|
||||||
}
|
}
|
||||||
m_imgui->end();
|
m_imgui->end();
|
||||||
|
|
||||||
// refresh view when needed
|
// refresh view when needed
|
||||||
if (m_need_reload) {
|
if (m_need_reload) {
|
||||||
m_need_reload = false;
|
m_need_reload = false;
|
||||||
bool close_on_end = (m_state == State::close_on_end);
|
bool close_on_end = (m_state.status == State::close_on_end);
|
||||||
// Reload visualization of mesh - change VBO, FBO on GPU
|
|
||||||
request_rerender();
|
request_rerender();
|
||||||
// set m_state must be before close() !!!
|
// set m_state.status must be before close() !!!
|
||||||
m_state = State::settings;
|
m_state.status = State::settings;
|
||||||
if (close_on_end) after_apply();
|
if (close_on_end) after_apply();
|
||||||
else init_model();
|
else init_model();
|
||||||
// Fix warning icon in object list
|
// Fix warning icon in object list
|
||||||
|
@ -330,6 +327,7 @@ void GLGizmoSimplify::after_apply() {
|
||||||
m_exist_preview = false;
|
m_exist_preview = false;
|
||||||
// fix hollowing, sla support points, modifiers, ...
|
// fix hollowing, sla support points, modifiers, ...
|
||||||
auto plater = wxGetApp().plater();
|
auto plater = wxGetApp().plater();
|
||||||
|
plater->take_snapshot(_u8L("Simplify ") + m_volume->name);
|
||||||
plater->changed_mesh(m_obj_index);
|
plater->changed_mesh(m_obj_index);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
@ -342,19 +340,12 @@ void GLGizmoSimplify::close() {
|
||||||
|
|
||||||
void GLGizmoSimplify::live_preview() {
|
void GLGizmoSimplify::live_preview() {
|
||||||
m_is_valid_result = false;
|
m_is_valid_result = false;
|
||||||
if (m_state != State::settings) {
|
if (m_state.status != State::settings) {
|
||||||
// already canceling process
|
// already canceling process
|
||||||
if (m_state == State::canceling) return;
|
if (m_state.status == State::canceling) return;
|
||||||
|
|
||||||
// wait until cancel
|
|
||||||
if (m_worker.joinable()) {
|
|
||||||
m_state = State::canceling;
|
|
||||||
m_dealy_process_cv.notify_one();
|
|
||||||
m_worker.join();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state = State::preview;
|
m_state.status = State::preview;
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,48 +378,29 @@ void GLGizmoSimplify::process()
|
||||||
|
|
||||||
// store previous state
|
// store previous state
|
||||||
auto plater = wxGetApp().plater();
|
auto plater = wxGetApp().plater();
|
||||||
plater->take_snapshot(_u8L("Simplify ") + m_volume->name);
|
// LUKAS: ???
|
||||||
plater->clear_before_change_mesh(m_obj_index);
|
plater->clear_before_change_mesh(m_obj_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_progress = 0;
|
m_state.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
|
// Checks that the UI thread did not request cancellation, throw if so.
|
||||||
uint32_t triangle_count = (m_configuration.use_count) ? m_configuration.wanted_count : 0;
|
std::function<void(void)> throw_on_cancel = [this]() {
|
||||||
float max_error = (!m_configuration.use_count) ? m_configuration.max_error : std::numeric_limits<float>::max();
|
if (m_state.status == State::canceling)
|
||||||
|
|
||||||
std::function<void(void)> throw_on_cancel = [&]() {
|
|
||||||
if (m_state == State::canceling) {
|
|
||||||
throw SimplifyCanceledException();
|
throw SimplifyCanceledException();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int64_t last = 0;
|
// Called by worker thread,
|
||||||
std::function<void(int)> statusfn = [this, &last](int percent) {
|
std::function<void(int)> statusfn = [this](int percent) {
|
||||||
m_progress = percent;
|
m_state.progress = percent;
|
||||||
|
|
||||||
// check max 4fps
|
|
||||||
int64_t now = m_parent.timestamp_now();
|
|
||||||
if ((now - last) < 250) return;
|
|
||||||
last = now;
|
|
||||||
|
|
||||||
request_rerender();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
indexed_triangle_set collapsed = *m_original_its; // copy
|
indexed_triangle_set collapsed = *m_original_its; // copy
|
||||||
|
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();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
its_quadric_edge_collapse(collapsed, triangle_count, &max_error, throw_on_cancel, statusfn);
|
its_quadric_edge_collapse(collapsed, triangle_count, &max_error, throw_on_cancel, statusfn);
|
||||||
|
@ -437,7 +409,7 @@ void GLGizmoSimplify::process()
|
||||||
m_exist_preview = true;
|
m_exist_preview = true;
|
||||||
} catch (SimplifyCanceledException &) {
|
} catch (SimplifyCanceledException &) {
|
||||||
// set state out of main thread
|
// set state out of main thread
|
||||||
m_state = State::settings;
|
m_state.status = State::settings;
|
||||||
}
|
}
|
||||||
// need to render last status fn to change bar graph to buttons
|
// need to render last status fn to change bar graph to buttons
|
||||||
request_rerender();
|
request_rerender();
|
||||||
|
@ -469,13 +441,13 @@ void GLGizmoSimplify::on_set_state()
|
||||||
|
|
||||||
// cancel processing
|
// cancel processing
|
||||||
if (empty_selection &&
|
if (empty_selection &&
|
||||||
m_state != State::settings &&
|
m_state.status != State::settings &&
|
||||||
m_state != State::canceling)
|
m_state.status != State::canceling)
|
||||||
m_state = State::canceling;
|
m_state.status = State::canceling;
|
||||||
|
|
||||||
// refuse outgoing during simlification
|
// refuse outgoing during simlification
|
||||||
// object is not selected when it is deleted(cancel and close gizmo)
|
// object is not selected when it is deleted(cancel and close gizmo)
|
||||||
if (m_state != State::settings && !empty_selection) {
|
if (m_state.status != State::settings && !empty_selection) {
|
||||||
GLGizmoBase::m_state = GLGizmoBase::On;
|
GLGizmoBase::m_state = GLGizmoBase::On;
|
||||||
auto notification_manager = wxGetApp().plater()->get_notification_manager();
|
auto notification_manager = wxGetApp().plater()->get_notification_manager();
|
||||||
notification_manager->push_notification(
|
notification_manager->push_notification(
|
||||||
|
|
|
@ -4,13 +4,11 @@
|
||||||
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
|
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
|
||||||
// which overrides our localization "L" macro.
|
// which overrides our localization "L" macro.
|
||||||
#include "GLGizmoBase.hpp"
|
#include "GLGizmoBase.hpp"
|
||||||
#include "slic3r/GUI/GLModel.hpp"
|
|
||||||
#include "GLGizmoPainterBase.hpp" // for render wireframe
|
#include "GLGizmoPainterBase.hpp" // for render wireframe
|
||||||
|
#include "slic3r/GUI/GLModel.hpp"
|
||||||
#include "admesh/stl.h" // indexed_triangle_set
|
#include "admesh/stl.h" // indexed_triangle_set
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
|
||||||
#include <chrono>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
@ -35,6 +33,7 @@ public:
|
||||||
const std::vector<size_t> &object_ids,
|
const std::vector<size_t> &object_ids,
|
||||||
const ModelObjectPtrs & objects,
|
const ModelObjectPtrs & objects,
|
||||||
NotificationManager & manager);
|
NotificationManager & manager);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual std::string on_get_name() const override;
|
virtual std::string on_get_name() const override;
|
||||||
virtual void on_render_input_window(float x, float y, float bottom_limit) override;
|
virtual void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||||
|
@ -48,6 +47,7 @@ protected:
|
||||||
virtual void on_render_for_picking() override{};
|
virtual void on_render_for_picking() override{};
|
||||||
|
|
||||||
virtual CommonGizmosDataID on_get_requirements() const;
|
virtual CommonGizmosDataID on_get_requirements() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void after_apply();
|
void after_apply();
|
||||||
void close();
|
void close();
|
||||||
|
@ -70,7 +70,7 @@ private:
|
||||||
|
|
||||||
bool m_move_to_center; // opening gizmo
|
bool m_move_to_center; // opening gizmo
|
||||||
|
|
||||||
std::atomic<int> m_progress; // percent of done work
|
|
||||||
ModelVolume *m_volume; // keep pointer to actual working volume
|
ModelVolume *m_volume; // keep pointer to actual working volume
|
||||||
size_t m_obj_index;
|
size_t m_obj_index;
|
||||||
|
|
||||||
|
@ -81,17 +81,22 @@ private:
|
||||||
std::atomic<bool> m_need_reload; // after simplify, glReload must be on main thread
|
std::atomic<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::mutex m_state_mutex;
|
||||||
std::condition_variable m_dealy_process_cv;
|
|
||||||
|
|
||||||
enum class State {
|
struct State {
|
||||||
settings,
|
enum Status {
|
||||||
preview, // simplify to show preview
|
settings,
|
||||||
close_on_end, // simplify with close on end
|
preview, // simplify to show preview
|
||||||
canceling // after button click, before canceled
|
close_on_end, // simplify with close on end
|
||||||
|
canceling // after button click, before canceled
|
||||||
|
};
|
||||||
|
|
||||||
|
Status status;
|
||||||
|
int progress; // percent of done work
|
||||||
|
indexed_triangle_set result;
|
||||||
};
|
};
|
||||||
std::atomic<State> m_state;
|
|
||||||
|
State m_state;
|
||||||
|
|
||||||
struct Configuration
|
struct Configuration
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue