Simplify dialog,
remove fast reduction - create mistake
This commit is contained in:
parent
89819c1c22
commit
b555910185
@ -111,63 +111,69 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::Text(_L("Limit by triangles").c_str());
|
if(ImGui::RadioButton("##use_error", !m_configuration.use_count)) {
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
|
||||||
// First initialization + fix triangle count
|
|
||||||
if (m_imgui->checkbox("##UseCount", m_configuration.use_count)) {
|
|
||||||
if (!m_configuration.use_count) m_configuration.use_error = true;
|
|
||||||
m_is_valid_result = false;
|
m_is_valid_result = false;
|
||||||
|
m_configuration.use_count = !m_configuration.use_count;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
m_imgui->disabled_begin(m_configuration.use_count);
|
||||||
|
ImGui::Text(_L("Detail level").c_str());
|
||||||
|
std::vector<std::string> reduce_captions = {
|
||||||
|
_u8L("Extra high"),
|
||||||
|
_u8L("High"),
|
||||||
|
_u8L("Medium"),
|
||||||
|
_u8L("Low"),
|
||||||
|
_u8L("Extra low")
|
||||||
|
};
|
||||||
|
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
||||||
|
ImGui::SetNextItemWidth(m_gui_cfg->input_width);
|
||||||
|
static int reduction = 3;
|
||||||
|
if(ImGui::SliderInt("##ReductionLevel", &reduction, 1, 5, reduce_captions[reduction-1].c_str())) {
|
||||||
|
m_is_valid_result = false;
|
||||||
|
if (reduction < 1) reduction = 1;
|
||||||
|
if (reduction > 5) reduction = 5;
|
||||||
|
switch (reduction) {
|
||||||
|
case 1: m_configuration.max_error = 1e-3f; break;
|
||||||
|
case 2: m_configuration.max_error = 1e-2f; break;
|
||||||
|
case 3: m_configuration.max_error = 0.1f; break;
|
||||||
|
case 4: m_configuration.max_error = 0.5f; break;
|
||||||
|
case 5: m_configuration.max_error = 1.f; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_imgui->disabled_end(); // !use_count
|
||||||
|
|
||||||
|
if (ImGui::RadioButton("##use_count", m_configuration.use_count)) {
|
||||||
|
m_is_valid_result = false;
|
||||||
|
m_configuration.use_count = !m_configuration.use_count;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// show preview result triangle count (percent)
|
||||||
|
if (m_need_reload && !m_configuration.use_count) {
|
||||||
|
m_configuration.wanted_count = static_cast<uint32_t>(m_volume->mesh().its.indices.size());
|
||||||
|
m_configuration.update_count(triangle_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_imgui->disabled_begin(!m_configuration.use_count);
|
m_imgui->disabled_begin(!m_configuration.use_count);
|
||||||
ImGui::Text(_L("Triangle count").c_str());
|
ImGui::Text(_L("Ratio").c_str());
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
||||||
int wanted_count = m_configuration.wanted_count;
|
int wanted_count = m_configuration.wanted_count;
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->input_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->input_width);
|
||||||
if (ImGui::SliderInt("##triangle_count", &wanted_count, min_triangle_count, triangle_count, "%d")) {
|
const char * format = (m_configuration.wanted_percent > 10)? "%.0f %%":
|
||||||
m_configuration.wanted_count = static_cast<uint32_t>(wanted_count);
|
((m_configuration.wanted_percent > 1)? "%.1f %%":"%.2f %%");
|
||||||
if (m_configuration.wanted_count < min_triangle_count)
|
if (ImGui::SliderFloat("##triangle_ratio", &m_configuration.wanted_percent, 0.f, 100.f, format)) {
|
||||||
m_configuration.wanted_count = min_triangle_count;
|
|
||||||
if (m_configuration.wanted_count > triangle_count)
|
|
||||||
m_configuration.wanted_count = triangle_count;
|
|
||||||
m_configuration.update_count(triangle_count);
|
|
||||||
m_is_valid_result = false;
|
m_is_valid_result = false;
|
||||||
}
|
if (m_configuration.wanted_percent < 0.f)
|
||||||
ImGui::Text(_L("Ratio").c_str());
|
m_configuration.wanted_percent = 0.01;
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
if (m_configuration.wanted_percent > 100.f)
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->input_small_width);
|
m_configuration.wanted_percent = 100.f;
|
||||||
const char * precision = (m_configuration.wanted_percent > 10)? "%.0f":
|
|
||||||
((m_configuration.wanted_percent > 1)? "%.1f":"%.2f");
|
|
||||||
float step = (m_configuration.wanted_percent > 10)? 1.f:
|
|
||||||
((m_configuration.wanted_percent > 1)? 0.1f : 0.01f);
|
|
||||||
if (ImGui::InputFloat("%", &m_configuration.wanted_percent, step, 10*step, precision)) {
|
|
||||||
if (m_configuration.wanted_percent > 100.f) m_configuration.wanted_percent = 100.f;
|
|
||||||
m_configuration.update_percent(triangle_count);
|
m_configuration.update_percent(triangle_count);
|
||||||
if (m_configuration.wanted_count < min_triangle_count) {
|
|
||||||
m_configuration.wanted_count = min_triangle_count;
|
|
||||||
m_configuration.update_count(triangle_count);
|
|
||||||
}
|
}
|
||||||
m_is_valid_result = false;
|
|
||||||
}
|
|
||||||
m_imgui->disabled_end(); // use_count
|
|
||||||
|
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
ImGui::Text(_L("Limit by error").c_str());
|
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
||||||
if (m_imgui->checkbox("##UseError", m_configuration.use_error)) {
|
ImGui::Text(_L("%d triangles").c_str(), m_configuration.wanted_count);
|
||||||
if (!m_configuration.use_error) m_configuration.use_count = true;
|
m_imgui->disabled_end(); // use_count
|
||||||
m_is_valid_result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_imgui->disabled_begin(!m_configuration.use_error);
|
|
||||||
ImGui::Text(_L("Max. error").c_str());
|
|
||||||
ImGui::SameLine(m_gui_cfg->bottom_left_width);
|
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->input_small_width);
|
|
||||||
if (ImGui::InputFloat("##maxError", &m_configuration.max_error, 0.01f, .1f, "%.2f")) {
|
|
||||||
if (m_configuration.max_error < 0.f) m_configuration.max_error = 0.f;
|
|
||||||
m_is_valid_result = false;
|
|
||||||
}
|
|
||||||
m_imgui->disabled_end(); // use_error
|
|
||||||
|
|
||||||
if (m_state == State::settings) {
|
if (m_state == State::settings) {
|
||||||
if (m_imgui->button(_L("Cancel"))) {
|
if (m_imgui->button(_L("Cancel"))) {
|
||||||
@ -256,8 +262,7 @@ void GLGizmoSimplify::process()
|
|||||||
m_worker = std::thread([this]() {
|
m_worker = std::thread([this]() {
|
||||||
// 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_error) ?
|
float max_error = (!m_configuration.use_count) ? m_configuration.max_error : std::numeric_limits<float>::max();
|
||||||
m_configuration.max_error : std::numeric_limits<float>::max();
|
|
||||||
|
|
||||||
std::function<void(void)> throw_on_cancel = [&]() {
|
std::function<void(void)> throw_on_cancel = [&]() {
|
||||||
if (m_state == State::canceling) {
|
if (m_state == State::canceling) {
|
||||||
@ -272,26 +277,17 @@ void GLGizmoSimplify::process()
|
|||||||
static int64_t last = 0;
|
static int64_t last = 0;
|
||||||
int64_t now = m_parent.timestamp_now();
|
int64_t now = m_parent.timestamp_now();
|
||||||
if ((now - last) < 250) return;
|
if ((now - last) < 250) return;
|
||||||
|
last = now;
|
||||||
|
|
||||||
request_rerender();
|
request_rerender();
|
||||||
};
|
};
|
||||||
|
|
||||||
indexed_triangle_set collapsed;
|
indexed_triangle_set collapsed = *m_original_its; // copy
|
||||||
if (m_last_error.has_value() && m_last_count.has_value() &&
|
|
||||||
(!m_configuration.use_count || triangle_count <= *m_last_count) &&
|
|
||||||
(!m_configuration.use_error || m_configuration.max_error <= *m_last_error)) {
|
|
||||||
// continue from last reduction - speed up
|
|
||||||
collapsed = m_volume->mesh().its; // small copy
|
|
||||||
} else {
|
|
||||||
collapsed = *m_original_its; // copy
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
set_its(collapsed);
|
set_its(collapsed);
|
||||||
m_is_valid_result = true;
|
m_is_valid_result = true;
|
||||||
m_last_count = triangle_count; // need to store last requirement, collapsed count could be count-1
|
|
||||||
m_last_error = max_error;
|
|
||||||
} catch (SimplifyCanceledException &) {
|
} catch (SimplifyCanceledException &) {
|
||||||
// set state out of main thread
|
// set state out of main thread
|
||||||
m_state = State::settings;
|
m_state = State::settings;
|
||||||
@ -348,20 +344,18 @@ void GLGizmoSimplify::on_set_state()
|
|||||||
|
|
||||||
void GLGizmoSimplify::create_gui_cfg() {
|
void GLGizmoSimplify::create_gui_cfg() {
|
||||||
if (m_gui_cfg.has_value()) return;
|
if (m_gui_cfg.has_value()) return;
|
||||||
|
|
||||||
int space_size = m_imgui->calc_text_size(":MM").x;
|
int space_size = m_imgui->calc_text_size(":MM").x;
|
||||||
GuiCfg cfg;
|
GuiCfg cfg;
|
||||||
cfg.top_left_width = std::max(m_imgui->calc_text_size(_L("Mesh name")).x,
|
cfg.top_left_width = std::max(m_imgui->calc_text_size(_L("Mesh name")).x,
|
||||||
m_imgui->calc_text_size(_L("Triangles")).x)
|
m_imgui->calc_text_size(_L("Triangles")).x)
|
||||||
+ space_size;
|
+ space_size;
|
||||||
|
|
||||||
|
const float radio_size = ImGui::GetFrameHeight();
|
||||||
cfg.bottom_left_width =
|
cfg.bottom_left_width =
|
||||||
std::max(
|
std::max(m_imgui->calc_text_size(_L("Detail level")).x,
|
||||||
std::max(m_imgui->calc_text_size(_L("Limit by triangles")).x,
|
m_imgui->calc_text_size(_L("Ratio")).x) +
|
||||||
std::max(m_imgui->calc_text_size(_L("Triangle count")).x,
|
space_size + radio_size;
|
||||||
m_imgui->calc_text_size(_L("Ratio")).x)),
|
|
||||||
std::max(m_imgui->calc_text_size(_L("Limit by error")).x,
|
|
||||||
m_imgui->calc_text_size(_L("Max. error")).x)) + space_size;
|
|
||||||
cfg.input_width = cfg.bottom_left_width;
|
cfg.input_width = cfg.bottom_left_width;
|
||||||
cfg.input_small_width = cfg.input_width * 0.8;
|
cfg.input_small_width = cfg.input_width * 0.8;
|
||||||
cfg.window_offset = cfg.input_width;
|
cfg.window_offset = cfg.input_width;
|
||||||
|
@ -44,9 +44,6 @@ private:
|
|||||||
|
|
||||||
std::optional<indexed_triangle_set> m_original_its;
|
std::optional<indexed_triangle_set> m_original_its;
|
||||||
|
|
||||||
std::optional<float> m_last_error; // for use previous reduction
|
|
||||||
std::optional<uint32_t> m_last_count;
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -60,12 +57,11 @@ private:
|
|||||||
|
|
||||||
struct Configuration
|
struct Configuration
|
||||||
{
|
{
|
||||||
bool use_count = true;
|
bool use_count = false;
|
||||||
// minimal triangle count
|
// minimal triangle count
|
||||||
float wanted_percent = 50.f;
|
float wanted_percent = 50.f;
|
||||||
uint32_t wanted_count = 0; // initialize by percents
|
uint32_t wanted_count = 0; // initialize by percents
|
||||||
|
|
||||||
bool use_error = false;
|
|
||||||
// maximal quadric error
|
// maximal quadric error
|
||||||
float max_error = 1.;
|
float max_error = 1.;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user