diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index b6dc3b37bb..8d5372c5e4 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -756,7 +756,14 @@ public: Preset& get_edited_preset() { return m_edited_preset; } const Preset& get_edited_preset() const { return m_edited_preset; } - const Preset& get_selected_preset_base() const { return *get_preset_base(m_presets[m_idx_selected]); } + // The root of the selected preset's inherits chain, or the selected preset itself when + // the chain names a preset that is not loaded (e.g. a vendor that is not installed). + const Preset& get_selected_preset_base() const + { + const Preset &selected = m_presets[m_idx_selected]; + const Preset *base = get_preset_base(selected); + return base ? *base : selected; + } // Return the last saved preset. // const Preset& get_saved_preset() const { return m_saved_preset; } diff --git a/src/slic3r/GUI/CreatePresetsDialog.cpp b/src/slic3r/GUI/CreatePresetsDialog.cpp index 0d5f688948..92925227ac 100644 --- a/src/slic3r/GUI/CreatePresetsDialog.cpp +++ b/src/slic3r/GUI/CreatePresetsDialog.cpp @@ -3151,7 +3151,7 @@ void CreatePrinterPresetDialog::set_current_visible_printer() m_printer_name_to_preset.clear(); for (const Preset &printer_preset : printer_presets) { if (!printer_preset.is_visible) continue; - if (preset_bundle->printers.get_preset_base(printer_preset)->name != printer_preset.name) continue; + if (preset_bundle->printers.get_preset_base(printer_preset) != &printer_preset) continue; if (auto printer_model = dynamic_cast(const_cast(printer_preset).config.option("printer_model", false))) { if (m_printer_name_to_preset.find(printer_model->value) == m_printer_name_to_preset.end()) { printer_choice.push_back(from_u8(printer_model->value)); @@ -4962,7 +4962,7 @@ void CreatePresetForPrinterDialog::get_visible_printer_and_compatible_filament_p if (filament_preset.is_default || !filament_preset.is_compatible || filament_preset.is_project_embedded) continue; ConfigOptionStrings *filament_types; const Preset * filament_preset_base = m_preset_bundle->filaments.get_preset_base(filament_preset); - if (filament_preset_base == &filament_preset) { + if (filament_preset_base == &filament_preset || filament_preset_base == nullptr) { filament_types = dynamic_cast(const_cast(&filament_preset)->config.option("filament_type")); } else { filament_types = dynamic_cast(const_cast(filament_preset_base)->config.option("filament_type")); diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index 7ea1452042..1b4927f08c 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -1219,6 +1219,24 @@ TEST_CASE("find_preset2 auto-matches removed Generic vendor profiles to the libr CHECK(bundle.filaments.find_preset2("BrandX Generic PETG", /*auto_match=*/true) == nullptr); } +TEST_CASE("The selected preset is its own base when its parent is not loaded", "[Preset]") +{ + PresetCollection printers(Preset::TYPE_PRINTER, Preset::printer_options(), + static_cast(FullPrintConfig::defaults())); + add_inmemory_preset(printers, "Printer"); + add_inmemory_preset(printers, "User Printer", "Printer"); + add_inmemory_preset(printers, "Orphan Printer", "Uninstalled Vendor Printer"); + + printers.select_preset_by_name("User Printer", true); + REQUIRE(printers.get_selected_preset_name() == "User Printer"); + CHECK(printers.get_selected_preset_base().name == "Printer"); + + printers.select_preset_by_name("Orphan Printer", true); + REQUIRE(printers.get_selected_preset_name() == "Orphan Printer"); + REQUIRE(printers.get_preset_base(printers.get_selected_preset()) == nullptr); + CHECK(printers.get_selected_preset_base().name == "Orphan Printer"); +} + TEST_CASE("Renamed parent is normalized into a loaded preset's inherits", "[Preset][Rename]") { ScopedTemporaryDir temp_dir;