mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-17 07:52:08 +00:00
fix compatible_prints/printers on load instead
This commit is contained in:
@@ -532,6 +532,9 @@ PresetsConfigSubstitutions PresetBundle::load_presets(AppConfig &config, Forward
|
||||
load_user_presets(dir_user_presets, substitution_rule);
|
||||
}
|
||||
|
||||
// Rewrite renamed compatible_printers / compatible_prints references before selection.
|
||||
this->normalize_compatible_presets();
|
||||
|
||||
this->update_multi_material_filament_presets();
|
||||
this->update_compatible(PresetSelectCompatibleType::Never);
|
||||
|
||||
@@ -752,6 +755,8 @@ PresetsConfigSubstitutions PresetBundle::load_project_embedded_presets(std::vect
|
||||
|
||||
//this->update_multi_material_filament_presets();
|
||||
//this->update_compatible(PresetSelectCompatibleType::Never);
|
||||
// Rewrite renamed compatible references before the caller (Plater) selects the project presets.
|
||||
this->normalize_compatible_presets();
|
||||
if (! errors_cummulative.empty())
|
||||
throw Slic3r::RuntimeError(errors_cummulative);
|
||||
|
||||
@@ -1122,6 +1127,9 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(AppConfig &
|
||||
this->printers.update_after_user_presets_loaded();
|
||||
}*/
|
||||
|
||||
// Rewrite renamed compatible references in synced user presets before compatibility is evaluated.
|
||||
this->normalize_compatible_presets();
|
||||
|
||||
this->update_multi_material_filament_presets();
|
||||
this->update_compatible(PresetSelectCompatibleType::Never);
|
||||
//this->load_selections(config, PresetPreferences());
|
||||
@@ -1807,6 +1815,9 @@ PresetsConfigSubstitutions PresetBundle::update_subscribed_presets(
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed to save bundle metadata to: " << metadata_save_path.string();
|
||||
}
|
||||
|
||||
// Rewrite renamed compatible references in synced user presets before compatibility is evaluated.
|
||||
this->normalize_compatible_presets();
|
||||
|
||||
this->update_multi_material_filament_presets();
|
||||
this->update_compatible(PresetSelectCompatibleType::Never);
|
||||
|
||||
@@ -5240,6 +5251,50 @@ void PresetBundle::update_multi_material_filament_presets(size_t to_delete_filam
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite a preset-name-list field (compatible_printers / compatible_prints) so references to a
|
||||
// renamed system preset point at the current name. Sibling-collection analog of
|
||||
// Preset::normalize_inherits: target.find_preset(name, false) resolves "renamed_from" recursively
|
||||
// and returns nullptr for unknown names, so we rewrite only on a positive, changed match and leave
|
||||
// user/deleted names untouched.
|
||||
static void normalize_compatible_field(Preset &preset, const char *field_key, PresetCollection &target)
|
||||
{
|
||||
auto *opt = preset.config.option<ConfigOptionStrings>(field_key);
|
||||
if (opt == nullptr)
|
||||
return;
|
||||
for (std::string &name : opt->values) {
|
||||
if (name.empty())
|
||||
continue;
|
||||
if (const Preset *resolved = target.find_preset(name, false); resolved != nullptr && resolved->name != name)
|
||||
name = resolved->name;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve compatible_printers / compatible_prints references that point at a renamed system preset
|
||||
// to the current name, mirroring Preset::normalize_inherits for the "inherits" field. Because these
|
||||
// fields reference presets in sibling collections (printers / prints / sla_prints), the resolution
|
||||
// cannot happen inside a single collection's load_presets() and runs here, after update_system_maps()
|
||||
// has built every collection's rename map. Must be called before selection so the rewritten stored
|
||||
// preset is copied into the edited preset by select_preset (no spurious "modified" flag).
|
||||
void PresetBundle::normalize_compatible_presets()
|
||||
{
|
||||
// compatible_printers references a printer preset; compatible_prints (filaments / SLA materials)
|
||||
// references a process preset. Skip system presets: they are the targets of renames, not holders
|
||||
// of stale references, and their vendor data must not be mutated. (begin()/end() skip defaults.)
|
||||
auto normalize = [](PresetCollection &holders, PresetCollection &printers, PresetCollection *processes) {
|
||||
for (Preset &p : holders) {
|
||||
if (p.is_system)
|
||||
continue;
|
||||
normalize_compatible_field(p, "compatible_printers", printers);
|
||||
if (processes != nullptr)
|
||||
normalize_compatible_field(p, "compatible_prints", *processes);
|
||||
}
|
||||
};
|
||||
normalize(this->prints, this->printers, nullptr);
|
||||
// normalize(this->sla_prints, this->printers, nullptr);
|
||||
normalize(this->filaments, this->printers, &this->prints);
|
||||
// normalize(this->sla_materials, this->printers, &this->sla_prints);
|
||||
}
|
||||
|
||||
void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible)
|
||||
{
|
||||
const Preset &printer_preset = this->printers.get_edited_preset();
|
||||
|
||||
@@ -448,6 +448,11 @@ public:
|
||||
void update_compatible(PresetSelectCompatibleType select_other_print_if_incompatible, PresetSelectCompatibleType select_other_filament_if_incompatible);
|
||||
void update_compatible(PresetSelectCompatibleType select_other_if_incompatible) { this->update_compatible(select_other_if_incompatible, select_other_if_incompatible); }
|
||||
|
||||
// Rewrite compatible_printers / compatible_prints references that point at a renamed system
|
||||
// preset to the current name, mirroring Preset::normalize_inherits for the "inherits" field.
|
||||
// Call after loading presets and before selection; requires update_system_maps() to have run.
|
||||
void normalize_compatible_presets();
|
||||
|
||||
// Set the is_visible flag for printer vendors, printer models and printer variants
|
||||
// based on the user configuration.
|
||||
// If the "vendor" section is missing, enable all models and variants of the particular vendor.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
@@ -298,3 +299,81 @@ TEST_CASE("Removed Generic parent is normalized into a loaded filament's inherit
|
||||
CHECK(bundle.filaments.get_preset_parent(*child)->name == "Generic PLA @System");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// A live reference to a preset's compatible_printers / compatible_prints list. Fetches the *stored*
|
||||
// preset (real=true) so writes and reads hit the same object; creates the option if absent.
|
||||
std::vector<std::string> &compatible_list(PresetCollection &coll, const std::string &preset_name, const char *field_key)
|
||||
{
|
||||
Preset *preset = coll.find_preset(preset_name, /*first_visible_if_not_found=*/false, /*real=*/true);
|
||||
REQUIRE(preset != nullptr);
|
||||
return preset->config.option<ConfigOptionStrings>(field_key, true)->values;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Renamed printer/process names are normalized into compatible lists on load", "[Preset][Rename]")
|
||||
{
|
||||
PresetBundle bundle;
|
||||
|
||||
// Current printer + process, each renamed from an older name.
|
||||
add_inmemory_preset(bundle.printers, "New Printer");
|
||||
set_renamed_from(bundle.printers, "New Printer", { "Old Printer" });
|
||||
add_inmemory_preset(bundle.prints, "New Process");
|
||||
set_renamed_from(bundle.prints, "New Process", { "Old Process" });
|
||||
|
||||
// A user process still compatible with the OLD printer name.
|
||||
add_inmemory_preset(bundle.prints, "My Process");
|
||||
compatible_list(bundle.prints, "My Process", "compatible_printers") = { "Old Printer" };
|
||||
|
||||
// A user filament referencing the OLD printer AND OLD process names, plus an unknown printer.
|
||||
add_inmemory_preset(bundle.filaments, "My Filament");
|
||||
compatible_list(bundle.filaments, "My Filament", "compatible_printers") = { "Old Printer", "Unknown Printer" };
|
||||
compatible_list(bundle.filaments, "My Filament", "compatible_prints") = { "Old Process" };
|
||||
|
||||
// Build the rename maps (done during system load in the real pipeline), then normalize.
|
||||
AppConfig app_config;
|
||||
bundle.load_installed_printers(app_config); // rebuilds every collection's rename map
|
||||
bundle.normalize_compatible_presets();
|
||||
|
||||
// The stale printer name in a process' compatible_printers is rewritten to the current name.
|
||||
CHECK(compatible_list(bundle.prints, "My Process", "compatible_printers") == std::vector<std::string>{ "New Printer" });
|
||||
|
||||
// The stale process name in a filament's compatible_prints is rewritten (this field has no
|
||||
// runtime rename fallback, so load-time normalization is the only fix).
|
||||
CHECK(compatible_list(bundle.filaments, "My Filament", "compatible_prints") == std::vector<std::string>{ "New Process" });
|
||||
|
||||
// The renamed printer is rewritten while the unknown/deleted name is preserved as-is.
|
||||
CHECK(compatible_list(bundle.filaments, "My Filament", "compatible_printers") ==
|
||||
(std::vector<std::string>{ "New Printer", "Unknown Printer" }));
|
||||
|
||||
// Normalizing rewrites config in place without flagging the preset dirty.
|
||||
CHECK_FALSE(bundle.prints.find_preset("My Process", false, true)->is_dirty);
|
||||
|
||||
// A system preset that already references the current name is left untouched (idempotent no-op).
|
||||
bundle.normalize_compatible_presets();
|
||||
CHECK(compatible_list(bundle.prints, "My Process", "compatible_printers") == std::vector<std::string>{ "New Printer" });
|
||||
}
|
||||
|
||||
TEST_CASE("compatible_prints on SLA materials resolves against sla_prints, not prints", "[Preset][Rename]")
|
||||
{
|
||||
PresetBundle bundle;
|
||||
|
||||
// A renamed SLA process, and a same-named FFF process that must NOT be picked up: resolving the
|
||||
// SLA material's compatible_prints against `prints` would wrongly rewrite to "Wrong FFF Process".
|
||||
add_inmemory_preset(bundle.sla_prints, "New SLA Process");
|
||||
set_renamed_from(bundle.sla_prints, "New SLA Process", { "Old SLA Process" });
|
||||
add_inmemory_preset(bundle.prints, "Wrong FFF Process");
|
||||
set_renamed_from(bundle.prints, "Wrong FFF Process", { "Old SLA Process" });
|
||||
|
||||
add_inmemory_preset(bundle.sla_materials, "My SLA Material");
|
||||
compatible_list(bundle.sla_materials, "My SLA Material", "compatible_prints") = { "Old SLA Process" };
|
||||
|
||||
AppConfig app_config;
|
||||
bundle.load_installed_printers(app_config);
|
||||
bundle.normalize_compatible_presets();
|
||||
|
||||
CHECK(compatible_list(bundle.sla_materials, "My SLA Material", "compatible_prints") ==
|
||||
std::vector<std::string>{ "New SLA Process" });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user