Fix reload from disk for STEP models after reopening a project (#12992) (#14591)

* Fix reload from disk for STEP models after reopening a project (#12992)

reload_from_disk matched reloaded source volumes with an exact
source.input_file string comparison. After a project is saved and
reopened, the stored source path is only the filename (the default,
non-full-path save) while a freshly re-imported volume carries a full
path, so the comparison never matched: reload fell into fail_list and
the "locate file" dialog was effectively useless for STEP models.

Fall back to a case-insensitive filename comparison when the exact
paths differ, so the existing same-folder source lookup (and the
locate dialog) can reload the model. Projects that stored absolute
source paths still match exactly as before; no 3mf format change.

* Add Preferences option to store full source paths in projects

Expose the existing export_sources_full_pathnames setting (previously
only editable in the config file) as a checkbox under Preferences >
General > Project. Enabling it stores absolute source paths in saved
projects, so "Reload from disk" works when the source file is kept in
a different folder than the project (companion to #12992).
This commit is contained in:
SoftFever
2026-07-05 16:40:00 +08:00
committed by GitHub
parent b68cb8b97b
commit 5ba5c6672d
2 changed files with 15 additions and 1 deletions

View File

@@ -8959,7 +8959,14 @@ void Plater::priv::reload_from_disk()
if (has_source && old_volume->source.object_idx < int(new_model.objects.size())) {
const ModelObject *obj = new_model.objects[old_volume->source.object_idx];
if (old_volume->source.volume_idx < int(obj->volumes.size())) {
if (obj->volumes[old_volume->source.volume_idx]->source.input_file == old_volume->source.input_file) {
const std::string &new_input_file = obj->volumes[old_volume->source.volume_idx]->source.input_file;
const std::string &old_input_file = old_volume->source.input_file;
// Orca: match on the exact source path first, then fall back to filename-only so reload
// still matches when the project stored a bare filename and the file was found next to
// the project (same-folder fallback) or picked via the locate dialog (#12992).
if (new_input_file == old_input_file ||
boost::algorithm::iequals(fs::path(new_input_file).filename().string(),
fs::path(old_input_file).filename().string())) {
new_volume_idx = old_volume->source.volume_idx;
new_object_idx = old_volume->source.object_idx;
match_found = true;

View File

@@ -1664,6 +1664,13 @@ void PreferencesDialog::create_items()
);
g_sizer->Add(item_draco_bits);
auto item_full_source_paths = create_item_checkbox(_L("Store full source file paths in projects"),
_L("If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so "
"\"Reload from disk\" still works when the source file is kept in a different folder than the project. "
"If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths."),
"export_sources_full_pathnames");
g_sizer->Add(item_full_source_paths);
//// GENERAL > Preset
g_sizer->Add(create_item_title(_L("Preset")), 1, wxEXPAND);