mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-30 01:12:01 +08:00
Fix for SPE-1845 Incorrectly imported filament profiles from 3MF or configuration ini.
+ Fix for SPE-1848 Crash on switch from MM printer to SM, when non-first filament is modified
This commit is contained in:
parent
34ad4d6e5d
commit
7280b2a0fb
@ -1376,6 +1376,10 @@ Preset& PresetCollection::select_preset(size_t idx)
|
||||
if (idx >= m_presets.size())
|
||||
idx = first_visible_idx();
|
||||
m_idx_selected = idx;
|
||||
if (!m_presets[idx].is_visible)
|
||||
// The newly selected preset can be activated -> make it visible.
|
||||
m_presets[idx].is_visible = true;
|
||||
|
||||
m_edited_preset = m_presets[idx];
|
||||
bool default_visible = ! m_default_suppressed || m_idx_selected < m_num_default_presets;
|
||||
for (size_t i = 0; i < m_num_default_presets; ++i)
|
||||
|
@ -1046,11 +1046,8 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
||||
}
|
||||
// Load the configs into this->filaments and make them active.
|
||||
std::vector<std::string> extr_names = std::vector<std::string>(configs.size());
|
||||
// To avoid incorrect selection of the first filament preset (means a value of Preset->m_idx_selected)
|
||||
// in a case when next added preset take a place of previosly selected preset,
|
||||
// we should add presets from last to first
|
||||
bool any_modified = false;
|
||||
for (int i = (int)configs.size()-1; i >= 0; i--) {
|
||||
for (int i = 0; i < (int)configs.size(); i++) {
|
||||
DynamicPrintConfig &cfg = configs[i];
|
||||
// Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
|
||||
cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1];
|
||||
@ -1059,15 +1056,18 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
|
||||
// Load all filament presets, but only select the first one in the preset dialog.
|
||||
auto [loaded, modified] = this->filaments.load_external_preset(name_or_path, name,
|
||||
(i < int(old_filament_profile_names->values.size())) ? old_filament_profile_names->values[i] : "",
|
||||
std::move(cfg),
|
||||
i == 0 ?
|
||||
PresetCollection::LoadAndSelect::Always :
|
||||
any_modified ?
|
||||
PresetCollection::LoadAndSelect::Never :
|
||||
PresetCollection::LoadAndSelect::OnlyIfModified);
|
||||
std::move(cfg),
|
||||
any_modified ? PresetCollection::LoadAndSelect::Never :
|
||||
PresetCollection::LoadAndSelect::OnlyIfModified);
|
||||
any_modified |= modified;
|
||||
extr_names[i] = loaded->name;
|
||||
}
|
||||
|
||||
// Check if some preset was selected after loading from config file.
|
||||
// ! Selected preset name is always the same as name of edited preset, if selection was applied
|
||||
if (this->filaments.get_selected_preset_name() != this->filaments.get_edited_preset().name)
|
||||
this->filaments.select_preset_by_name(extr_names[0], true);
|
||||
|
||||
// create extruders_filaments only when all filaments are loaded
|
||||
for (size_t id = 0; id < extr_names.size(); ++id)
|
||||
this->extruders_filaments.emplace_back(ExtruderFilaments(&filaments, id, extr_names[id]));
|
||||
@ -1806,7 +1806,21 @@ void PresetBundle::update_filaments_compatible(PresetSelectCompatibleType select
|
||||
else
|
||||
update_filament_compatible(extruder_idx);
|
||||
|
||||
if (this->filaments.get_idx_selected() == size_t(-1))
|
||||
// validate selection in filaments
|
||||
bool invalid_selection = this->filaments.get_idx_selected() == size_t(-1);
|
||||
if (!invalid_selection) {
|
||||
invalid_selection = true;
|
||||
const std::string selected_filament_name = this->filaments.get_selected_preset_name();
|
||||
for (const auto& extruder : extruders_filaments)
|
||||
if (const std::string& selected_extr_filament_name = extruder.get_selected_preset_name();
|
||||
selected_extr_filament_name == selected_filament_name) {
|
||||
invalid_selection = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// select valid filament from first extruder
|
||||
if (invalid_selection)
|
||||
this->filaments.select_preset(extruders_filaments[0].get_selected_idx());
|
||||
}
|
||||
|
||||
|
@ -2864,6 +2864,9 @@ void GUI_App::load_current_presets(bool check_printer_presets_ /*= true*/)
|
||||
// Mark the plater to update print bed by tab->load_current_preset() from Plater::on_config_change().
|
||||
this->plater()->force_print_bed_update();
|
||||
}
|
||||
else if (tab->type() == Preset::TYPE_FILAMENT)
|
||||
// active extruder can be changed in a respect to the new loaded configurations, if some filament preset will be modified
|
||||
static_cast<TabFilament*>(tab)->invalidate_active_extruder();
|
||||
tab->load_current_preset();
|
||||
}
|
||||
}
|
||||
|
@ -1986,8 +1986,16 @@ void TabFilament::update_extruder_combobox()
|
||||
m_extruders_cb->Append(format_wxstr("%1% %2%", _L("Extruder"), id), *get_bmp_bundle("funnel"));
|
||||
}
|
||||
|
||||
if (m_active_extruder >= int(extruder_cnt))
|
||||
if (m_active_extruder >= int(extruder_cnt)) {
|
||||
m_active_extruder = 0;
|
||||
// update selected and, as a result, editing preset
|
||||
const std::string& preset_name = m_preset_bundle->extruders_filaments[0].get_selected_preset_name();
|
||||
m_presets->select_preset_by_name(preset_name, true);
|
||||
|
||||
// To avoid inconsistance between value of active_extruder in FilamentTab and TabPresetComboBox,
|
||||
// which can causes a crash on switch preset from MM printer to SM printer
|
||||
m_presets_choice->set_active_extruder(m_active_extruder);
|
||||
}
|
||||
|
||||
m_extruders_cb->SetSelection(m_active_extruder);
|
||||
}
|
||||
@ -2317,12 +2325,37 @@ void TabFilament::sys_color_changed()
|
||||
|
||||
void TabFilament::load_current_preset()
|
||||
{
|
||||
const std::string& selected_filament_name = m_presets->get_selected_preset_name();
|
||||
if (m_active_extruder < 0) {
|
||||
// active extruder was invalidated before load new project file or configuration,
|
||||
// so we have to update active extruder selection from selected filament
|
||||
const std::string& edited_filament_name = m_presets->get_edited_preset().name;
|
||||
assert(!selected_filament_name.empty() && selected_filament_name == edited_filament_name);
|
||||
|
||||
for (int i = 0; i < int(m_preset_bundle->extruders_filaments.size()); i++) {
|
||||
const std::string& selected_extr_filament_name = m_preset_bundle->extruders_filaments[i].get_selected_preset_name();
|
||||
if (selected_extr_filament_name == edited_filament_name) {
|
||||
m_active_extruder = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(m_active_extruder >= 0);
|
||||
|
||||
m_presets_choice->set_active_extruder(m_active_extruder);
|
||||
if (m_active_extruder != m_extruders_cb->GetSelection())
|
||||
m_extruders_cb->Select(m_active_extruder);
|
||||
}
|
||||
|
||||
assert(m_active_extruder >= 0 && m_active_extruder < m_preset_bundle->extruders_filaments.size());
|
||||
const std::string& selected_extr_filament_name = m_preset_bundle->extruders_filaments[m_active_extruder].get_selected_preset_name();
|
||||
const std::string& selected_filament_name = m_presets->get_selected_preset_name();
|
||||
if (selected_extr_filament_name != selected_filament_name)
|
||||
if (selected_extr_filament_name != selected_filament_name) {
|
||||
m_presets->select_preset_by_name(selected_extr_filament_name, false);
|
||||
|
||||
// To avoid inconsistance between value of active_extruder in FilamentTab and TabPresetComboBox,
|
||||
// which can causes a crash on switch preset from MM printer to SM printer
|
||||
m_presets_choice->set_active_extruder(m_active_extruder);
|
||||
}
|
||||
|
||||
Tab::load_current_preset();
|
||||
}
|
||||
|
||||
@ -3639,8 +3672,17 @@ bool Tab::select_preset(std::string preset_name, bool delete_current /*=false*/,
|
||||
for (PresetUpdate &pu : updates) {
|
||||
pu.old_preset_dirty = (old_printer_technology == pu.technology) && pu.presets->current_is_dirty();
|
||||
pu.new_preset_compatible = (new_printer_technology == pu.technology) && is_compatible_with_printer(pu.presets->get_edited_preset_with_vendor_profile(), new_printer_preset_with_vendor_profile);
|
||||
bool force_update_edited_preset = false;
|
||||
if (pu.tab_type == Preset::TYPE_FILAMENT && pu.new_preset_compatible) {
|
||||
// check if edited preset will be still correct after selection new printer
|
||||
const int active_extruder = dynamic_cast<const TabFilament*>(wxGetApp().get_tab(Preset::TYPE_FILAMENT))->get_active_extruder();
|
||||
const int extruder_count_new = int(dynamic_cast<const ConfigOptionFloats*>(new_printer_preset.config.option("nozzle_diameter"))->size());
|
||||
// if active_extruder is bigger than extruders_count,
|
||||
// then it means that edited filament preset will be changed and we have to check this changes
|
||||
force_update_edited_preset = active_extruder >= extruder_count_new;
|
||||
}
|
||||
if (!canceled)
|
||||
canceled = pu.old_preset_dirty && !pu.new_preset_compatible && !may_discard_current_dirty_preset(pu.presets, preset_name);
|
||||
canceled = pu.old_preset_dirty && (!pu.new_preset_compatible || force_update_edited_preset) && !may_discard_current_dirty_preset(pu.presets, preset_name);
|
||||
}
|
||||
if (!canceled) {
|
||||
for (PresetUpdate &pu : updates) {
|
||||
|
@ -469,6 +469,7 @@ public:
|
||||
// set actiev extruder and update preset combobox if needed
|
||||
// return false, if new preset wasn't selected
|
||||
bool set_active_extruder(int new_selected_extruder);
|
||||
void invalidate_active_extruder() { m_active_extruder = -1; }
|
||||
void update_extruder_combobox();
|
||||
int get_active_extruder() const { return m_active_extruder; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user