mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-12 03:27:55 +00:00
improved mixed filament ui perf
This commit is contained in:
@@ -10,10 +10,18 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <set>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
static uint64_t canonical_pair_key(unsigned int a, unsigned int b)
|
||||||
|
{
|
||||||
|
const unsigned int lo = std::min(a, b);
|
||||||
|
const unsigned int hi = std::max(a, b);
|
||||||
|
return (uint64_t(lo) << 32) | uint64_t(hi);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Colour helpers (internal)
|
// Colour helpers (internal)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -738,9 +746,13 @@ void MixedFilamentManager::auto_generate(const std::vector<std::string> &filamen
|
|||||||
|
|
||||||
std::vector<MixedFilament> custom_rows;
|
std::vector<MixedFilament> custom_rows;
|
||||||
custom_rows.reserve(old.size());
|
custom_rows.reserve(old.size());
|
||||||
|
std::unordered_map<uint64_t, const MixedFilament *> old_auto_rows;
|
||||||
|
old_auto_rows.reserve(old.size());
|
||||||
for (const MixedFilament &prev : old) {
|
for (const MixedFilament &prev : old) {
|
||||||
if (!prev.custom)
|
if (!prev.custom) {
|
||||||
|
old_auto_rows.emplace(canonical_pair_key(prev.component_a, prev.component_b), &prev);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (prev.component_a == 0 || prev.component_b == 0 || prev.component_a > n || prev.component_b > n || prev.component_a == prev.component_b)
|
if (prev.component_a == 0 || prev.component_b == 0 || prev.component_a > n || prev.component_b > n || prev.component_a == prev.component_b)
|
||||||
continue;
|
continue;
|
||||||
MixedFilament custom = prev;
|
MixedFilament custom = prev;
|
||||||
@@ -762,18 +774,14 @@ void MixedFilamentManager::auto_generate(const std::vector<std::string> &filamen
|
|||||||
mf.custom = false;
|
mf.custom = false;
|
||||||
mf.origin_auto = true;
|
mf.origin_auto = true;
|
||||||
|
|
||||||
// Try to preserve previous settings.
|
const auto it_prev = old_auto_rows.find(canonical_pair_key(mf.component_a, mf.component_b));
|
||||||
for (const auto &prev : old) {
|
if (it_prev != old_auto_rows.end()) {
|
||||||
if (!prev.custom &&
|
const MixedFilament &prev = *it_prev->second;
|
||||||
prev.component_a == mf.component_a &&
|
mf.enabled = prev.enabled;
|
||||||
prev.component_b == mf.component_b) {
|
mf.deleted = prev.deleted;
|
||||||
mf.enabled = prev.enabled;
|
mf.stable_id = prev.stable_id;
|
||||||
mf.deleted = prev.deleted;
|
if (mf.deleted)
|
||||||
mf.stable_id = prev.stable_id;
|
mf.enabled = false;
|
||||||
if (mf.deleted)
|
|
||||||
mf.enabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mf.stable_id = normalize_stable_id(mf.stable_id);
|
mf.stable_id = normalize_stable_id(mf.stable_id);
|
||||||
m_mixed.push_back(mf);
|
m_mixed.push_back(mf);
|
||||||
@@ -931,21 +939,23 @@ void MixedFilamentManager::load_custom_entries(const std::string &serialized, co
|
|||||||
size_t appended_auto = 0;
|
size_t appended_auto = 0;
|
||||||
size_t skipped_rows = 0;
|
size_t skipped_rows = 0;
|
||||||
|
|
||||||
auto canonical_pair = [](unsigned int a, unsigned int b) {
|
std::vector<const MixedFilament *> auto_rows_in_order;
|
||||||
return std::make_pair(std::min(a, b), std::max(a, b));
|
auto_rows_in_order.reserve(m_mixed.size());
|
||||||
};
|
std::unordered_map<uint64_t, const MixedFilament *> auto_rows_by_pair;
|
||||||
|
auto_rows_by_pair.reserve(m_mixed.size());
|
||||||
std::vector<MixedFilament> auto_rows;
|
|
||||||
auto_rows.reserve(m_mixed.size());
|
|
||||||
for (const MixedFilament &mf : m_mixed) {
|
for (const MixedFilament &mf : m_mixed) {
|
||||||
if (!mf.custom)
|
if (!mf.custom) {
|
||||||
auto_rows.push_back(mf);
|
auto_rows_in_order.push_back(&mf);
|
||||||
|
auto_rows_by_pair.emplace(canonical_pair_key(mf.component_a, mf.component_b), &mf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MixedFilament> rebuilt;
|
std::vector<MixedFilament> rebuilt;
|
||||||
rebuilt.reserve(m_mixed.size() + 8);
|
rebuilt.reserve(m_mixed.size() + 8);
|
||||||
std::set<std::pair<unsigned int, unsigned int>> consumed_auto_pairs;
|
std::unordered_set<uint64_t> consumed_auto_pairs;
|
||||||
std::set<uint64_t> used_stable_ids;
|
consumed_auto_pairs.reserve(auto_rows_by_pair.size());
|
||||||
|
std::unordered_set<uint64_t> used_stable_ids;
|
||||||
|
used_stable_ids.reserve(m_mixed.size() + 8);
|
||||||
auto dedupe_stable_id = [this, &used_stable_ids](uint64_t stable_id) {
|
auto dedupe_stable_id = [this, &used_stable_ids](uint64_t stable_id) {
|
||||||
stable_id = normalize_stable_id(stable_id);
|
stable_id = normalize_stable_id(stable_id);
|
||||||
if (used_stable_ids.insert(stable_id).second)
|
if (used_stable_ids.insert(stable_id).second)
|
||||||
@@ -991,31 +1001,29 @@ void MixedFilamentManager::load_custom_entries(const std::string &serialized, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!custom) {
|
if (!custom) {
|
||||||
const auto key = canonical_pair(a, b);
|
const uint64_t key = canonical_pair_key(a, b);
|
||||||
if (consumed_auto_pairs.count(key) != 0) {
|
if (consumed_auto_pairs.count(key) != 0) {
|
||||||
++skipped_rows;
|
++skipped_rows;
|
||||||
BOOST_LOG_TRIVIAL(warning) << "MixedFilamentManager::load_custom_entries duplicate auto row"
|
BOOST_LOG_TRIVIAL(warning) << "MixedFilamentManager::load_custom_entries duplicate auto row"
|
||||||
<< ", row=" << row
|
<< ", row=" << row
|
||||||
<< ", a=" << key.first
|
<< ", a=" << std::min(a, b)
|
||||||
<< ", b=" << key.second;
|
<< ", b=" << std::max(a, b);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it_auto = std::find_if(auto_rows.begin(), auto_rows.end(), [key, canonical_pair](const MixedFilament &mf) {
|
auto it_auto = auto_rows_by_pair.find(key);
|
||||||
return canonical_pair(mf.component_a, mf.component_b) == key;
|
if (it_auto == auto_rows_by_pair.end()) {
|
||||||
});
|
|
||||||
if (it_auto == auto_rows.end()) {
|
|
||||||
++skipped_rows;
|
++skipped_rows;
|
||||||
BOOST_LOG_TRIVIAL(warning) << "MixedFilamentManager::load_custom_entries auto row missing after regenerate"
|
BOOST_LOG_TRIVIAL(warning) << "MixedFilamentManager::load_custom_entries auto row missing after regenerate"
|
||||||
<< ", row=" << row
|
<< ", row=" << row
|
||||||
<< ", a=" << key.first
|
<< ", a=" << std::min(a, b)
|
||||||
<< ", b=" << key.second;
|
<< ", b=" << std::max(a, b);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MixedFilament mf = *it_auto;
|
MixedFilament mf = *it_auto->second;
|
||||||
mf.component_a = key.first;
|
mf.component_a = std::min(a, b);
|
||||||
mf.component_b = key.second;
|
mf.component_b = std::max(a, b);
|
||||||
mf.stable_id = dedupe_stable_id(stable_id != 0 ? stable_id : mf.stable_id);
|
mf.stable_id = dedupe_stable_id(stable_id != 0 ? stable_id : mf.stable_id);
|
||||||
mf.enabled = enabled;
|
mf.enabled = enabled;
|
||||||
mf.pointillism_all_filaments = pointillism_all_filaments;
|
mf.pointillism_all_filaments = pointillism_all_filaments;
|
||||||
@@ -1064,13 +1072,17 @@ void MixedFilamentManager::load_custom_entries(const std::string &serialized, co
|
|||||||
|
|
||||||
// Keep any newly generated auto rows that were not present in serialized
|
// Keep any newly generated auto rows that were not present in serialized
|
||||||
// definitions and append them at the end to preserve existing virtual IDs.
|
// definitions and append them at the end to preserve existing virtual IDs.
|
||||||
for (const MixedFilament &auto_mf : auto_rows) {
|
for (const MixedFilament *auto_mf_ptr : auto_rows_in_order) {
|
||||||
const auto key = canonical_pair(auto_mf.component_a, auto_mf.component_b);
|
if (auto_mf_ptr == nullptr)
|
||||||
|
continue;
|
||||||
|
const uint64_t key = canonical_pair_key(auto_mf_ptr->component_a, auto_mf_ptr->component_b);
|
||||||
if (consumed_auto_pairs.count(key) != 0)
|
if (consumed_auto_pairs.count(key) != 0)
|
||||||
continue;
|
continue;
|
||||||
MixedFilament mf = auto_mf;
|
MixedFilament mf = *auto_mf_ptr;
|
||||||
mf.component_a = key.first;
|
const unsigned int lo = std::min(mf.component_a, mf.component_b);
|
||||||
mf.component_b = key.second;
|
const unsigned int hi = std::max(mf.component_a, mf.component_b);
|
||||||
|
mf.component_a = lo;
|
||||||
|
mf.component_b = hi;
|
||||||
mf.stable_id = dedupe_stable_id(mf.stable_id);
|
mf.stable_id = dedupe_stable_id(mf.stable_id);
|
||||||
mf.custom = false;
|
mf.custom = false;
|
||||||
mf.origin_auto = true;
|
mf.origin_auto = true;
|
||||||
|
|||||||
@@ -658,6 +658,7 @@ struct Sidebar::priv
|
|||||||
Button* m_btn_add_pattern = nullptr; // Add pattern button
|
Button* m_btn_add_pattern = nullptr; // Add pattern button
|
||||||
Button* m_btn_toggle_mixed_filaments = nullptr; // Collapse/expand toggle button
|
Button* m_btn_toggle_mixed_filaments = nullptr; // Collapse/expand toggle button
|
||||||
bool m_mixed_filaments_collapsed = false; // Collapse state
|
bool m_mixed_filaments_collapsed = false; // Collapse state
|
||||||
|
bool m_skip_mixed_filament_sync_once = false; // Local edits already mutated manager in place.
|
||||||
std::unordered_set<size_t> m_expanded_mixed_filament_rows; // Expanded row editors
|
std::unordered_set<size_t> m_expanded_mixed_filament_rows; // Expanded row editors
|
||||||
wxStaticLine* m_staticline2;
|
wxStaticLine* m_staticline2;
|
||||||
wxPanel* m_panel_project_title;
|
wxPanel* m_panel_project_title;
|
||||||
@@ -1471,7 +1472,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
// Persist the custom entries so they survive the clear/load cycle in update_mixed_filament_panel
|
// Persist the custom entries so they survive the clear/load cycle in update_mixed_filament_panel
|
||||||
if (ConfigOptionString *opt = wxGetApp().preset_bundle->project_config.option<ConfigOptionString>("mixed_filament_definitions"))
|
if (ConfigOptionString *opt = wxGetApp().preset_bundle->project_config.option<ConfigOptionString>("mixed_filament_definitions"))
|
||||||
opt->value = mgr.serialize_custom_entries();
|
opt->value = mgr.serialize_custom_entries();
|
||||||
update_mixed_filament_panel();
|
update_mixed_filament_panel(false);
|
||||||
m_scrolled_sizer->Layout();
|
m_scrolled_sizer->Layout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1497,7 +1498,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||||||
// Persist the custom entries so they survive the clear/load cycle in update_mixed_filament_panel
|
// Persist the custom entries so they survive the clear/load cycle in update_mixed_filament_panel
|
||||||
if (ConfigOptionString *opt = wxGetApp().preset_bundle->project_config.option<ConfigOptionString>("mixed_filament_definitions"))
|
if (ConfigOptionString *opt = wxGetApp().preset_bundle->project_config.option<ConfigOptionString>("mixed_filament_definitions"))
|
||||||
opt->value = mgr.serialize_custom_entries();
|
opt->value = mgr.serialize_custom_entries();
|
||||||
update_mixed_filament_panel();
|
update_mixed_filament_panel(false);
|
||||||
m_scrolled_sizer->Layout();
|
m_scrolled_sizer->Layout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2266,12 +2267,16 @@ void Sidebar::on_filaments_change(size_t num_filaments)
|
|||||||
if (num_filaments == choices.size()) {
|
if (num_filaments == choices.size()) {
|
||||||
// Project load may keep the same physical filament count while mixed
|
// Project load may keep the same physical filament count while mixed
|
||||||
// definitions changed. Refresh mixed panel even without count changes.
|
// definitions changed. Refresh mixed panel even without count changes.
|
||||||
|
const bool sync_manager = !p->m_skip_mixed_filament_sync_once;
|
||||||
|
p->m_skip_mixed_filament_sync_once = false;
|
||||||
update_ui_from_settings();
|
update_ui_from_settings();
|
||||||
update_dynamic_filament_list();
|
update_dynamic_filament_list();
|
||||||
update_mixed_filament_panel();
|
update_mixed_filament_panel(sync_manager);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->m_skip_mixed_filament_sync_once = false;
|
||||||
|
|
||||||
if (choices.size() == 1 || num_filaments == 1)
|
if (choices.size() == 1 || num_filaments == 1)
|
||||||
choices[0]->GetDropDown().Invalidate();
|
choices[0]->GetDropDown().Invalidate();
|
||||||
|
|
||||||
@@ -3867,12 +3872,15 @@ void MixedFilamentConfigPanel::update_preview()
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void Sidebar::update_mixed_filament_panel()
|
void Sidebar::update_mixed_filament_panel(bool sync_manager)
|
||||||
{
|
{
|
||||||
// Check for new collapsible structure
|
// Check for new collapsible structure
|
||||||
if (!p->m_panel_mixed_filaments_title || !p->m_panel_mixed_filaments_content)
|
if (!p->m_panel_mixed_filaments_title || !p->m_panel_mixed_filaments_content)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wxWindowUpdateLocker noUpdates_sidebar(this);
|
||||||
|
wxWindowUpdateLocker noUpdates_mixed_panel(p->m_panel_mixed_filaments_content);
|
||||||
|
|
||||||
auto refresh_model_canvas_colors = []() {
|
auto refresh_model_canvas_colors = []() {
|
||||||
Plater *plater = wxGetApp().plater();
|
Plater *plater = wxGetApp().plater();
|
||||||
if (plater == nullptr)
|
if (plater == nullptr)
|
||||||
@@ -4292,10 +4300,12 @@ void Sidebar::update_mixed_filament_panel()
|
|||||||
const std::string mixed_definitions = get_mixed_string("mixed_filament_definitions");
|
const std::string mixed_definitions = get_mixed_string("mixed_filament_definitions");
|
||||||
|
|
||||||
auto &mixed_mgr = preset_bundle->mixed_filaments;
|
auto &mixed_mgr = preset_bundle->mixed_filaments;
|
||||||
mixed_mgr.auto_generate(physical_colors);
|
if (sync_manager) {
|
||||||
mixed_mgr.clear_custom_entries();
|
mixed_mgr.auto_generate(physical_colors);
|
||||||
mixed_mgr.load_custom_entries(mixed_definitions, physical_colors);
|
mixed_mgr.clear_custom_entries();
|
||||||
mixed_mgr.apply_gradient_settings(gradient_mode, lower_bound, upper_bound, advanced_dithering);
|
mixed_mgr.load_custom_entries(mixed_definitions, physical_colors);
|
||||||
|
mixed_mgr.apply_gradient_settings(gradient_mode, lower_bound, upper_bound, advanced_dithering);
|
||||||
|
}
|
||||||
|
|
||||||
// During project load, sidebar may refresh before physical filament combos
|
// During project load, sidebar may refresh before physical filament combos
|
||||||
// finish syncing. Avoid overwriting persisted mixed definitions while the
|
// finish syncing. Avoid overwriting persisted mixed definitions while the
|
||||||
@@ -4477,8 +4487,10 @@ void Sidebar::update_mixed_filament_panel()
|
|||||||
mgr.apply_gradient_settings(mode, lo, hi, advanced);
|
mgr.apply_gradient_settings(mode, lo, hi, advanced);
|
||||||
update_dynamic_filament_list();
|
update_dynamic_filament_list();
|
||||||
|
|
||||||
if (rebuild_virtual_id_remap && wxGetApp().plater())
|
if (rebuild_virtual_id_remap && wxGetApp().plater()) {
|
||||||
|
p->m_skip_mixed_filament_sync_once = true;
|
||||||
wxGetApp().plater()->on_filaments_change(num_physical);
|
wxGetApp().plater()->on_filaments_change(num_physical);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t visible_mixed_idx = 0;
|
size_t visible_mixed_idx = 0;
|
||||||
@@ -4603,8 +4615,10 @@ void Sidebar::update_mixed_filament_panel()
|
|||||||
notify_mixed_change();
|
notify_mixed_change();
|
||||||
if (wxGetApp().plater())
|
if (wxGetApp().plater())
|
||||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||||
if (wxGetApp().plater())
|
if (wxGetApp().plater()) {
|
||||||
|
p->m_skip_mixed_filament_sync_once = true;
|
||||||
wxGetApp().plater()->on_filaments_change(num_physical);
|
wxGetApp().plater()->on_filaments_change(num_physical);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public:
|
|||||||
void edit_filament();
|
void edit_filament();
|
||||||
|
|
||||||
void on_filaments_delete(size_t filament_id);
|
void on_filaments_delete(size_t filament_id);
|
||||||
void update_mixed_filament_panel();
|
void update_mixed_filament_panel(bool sync_manager = true);
|
||||||
// BBS
|
// BBS
|
||||||
void on_bed_type_change(BedType bed_type);
|
void on_bed_type_change(BedType bed_type);
|
||||||
void load_ams_list(std::string const & device, MachineObject* obj);
|
void load_ams_list(std::string const & device, MachineObject* obj);
|
||||||
|
|||||||
Reference in New Issue
Block a user