diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 7f2fae7aa0..d6654d817a 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -52,4 +52,7 @@ // Enable fix for view toolbar background not showing up on Mac with dark mode #define ENABLE_VIEW_TOOLBAR_BACKGROUND_FIX (1 && ENABLE_2_2_0_ALPHA1) +// Enable selection for missing files in reload from disk command +#define ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION (1 && ENABLE_2_2_0_ALPHA1) + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 028414d604..5b97ce8215 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3203,12 +3203,67 @@ void Plater::priv::reload_from_disk() // collects paths of files to load std::vector input_paths; +#if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION + std::vector missing_input_paths; +#endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION for (const SelectedVolume& v : selected_volumes) { +#if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION + const ModelObject* object = model.objects[v.object_idx]; + const ModelVolume* volume = object->volumes[v.volume_idx]; + + if (!volume->source.input_file.empty()) + { + if (fs::exists(volume->source.input_file)) + input_paths.push_back(volume->source.input_file); + else + missing_input_paths.push_back(volume->source.input_file); + } +#else const ModelVolume* volume = model.objects[v.object_idx]->volumes[v.volume_idx]; if (!volume->source.input_file.empty() && boost::filesystem::exists(volume->source.input_file)) input_paths.push_back(volume->source.input_file); +#endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION } + +#if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION + std::sort(missing_input_paths.begin(), missing_input_paths.end()); + missing_input_paths.erase(std::unique(missing_input_paths.begin(), missing_input_paths.end()), missing_input_paths.end()); + + while (!missing_input_paths.empty()) + { + // ask user to select the missing file + std::string search = missing_input_paths.back().string(); + wxFileDialog dialog(q, _(L("Please select the file to reload:")), "", search, file_wildcards(FT_MODEL), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() != wxID_OK) + return; + + std::string sel_filename_path = dialog.GetPath().ToUTF8().data(); + std::string sel_filename = fs::path(sel_filename_path).filename().string(); + if (boost::algorithm::iends_with(search, sel_filename)) + { + input_paths.push_back(sel_filename_path); + missing_input_paths.pop_back(); + + std::string sel_path = fs::path(sel_filename_path).remove_filename().string(); + + std::vector::iterator it = missing_input_paths.begin(); + while (it != missing_input_paths.end()) + { + // try to use the path of the selected file with all remaining missing files + std::string repathed_filename = sel_path + "/" + it->filename().string(); + if (fs::exists(repathed_filename)) + { + input_paths.push_back(repathed_filename); + it = missing_input_paths.erase(it); + } + else + ++it; + } + } + } +#endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION + std::sort(input_paths.begin(), input_paths.end()); input_paths.erase(std::unique(input_paths.begin(), input_paths.end()), input_paths.end()); @@ -3242,22 +3297,20 @@ void Plater::priv::reload_from_disk() if (old_volume->source.input_file == path) { - if (new_object_idx < (int)new_model.objects.size()) + assert(new_object_idx < (int)new_model.objects.size()); + ModelObject* new_model_object = new_model.objects[new_object_idx]; + if (new_volume_idx < (int)new_model_object->volumes.size()) { - ModelObject* new_model_object = new_model.objects[new_object_idx]; - if (new_volume_idx < (int)new_model_object->volumes.size()) - { - old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]); - ModelVolume* new_volume = old_model_object->volumes.back(); - new_volume->set_new_unique_id(); - new_volume->config.apply(old_volume->config); - new_volume->set_type(old_volume->type()); - new_volume->set_material_id(old_volume->material_id()); - new_volume->set_transformation(old_volume->get_transformation()); - new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); - std::swap(old_model_object->volumes[old_v.volume_idx], old_model_object->volumes.back()); - old_model_object->delete_volume(old_model_object->volumes.size() - 1); - } + old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]); + ModelVolume* new_volume = old_model_object->volumes.back(); + new_volume->set_new_unique_id(); + new_volume->config.apply(old_volume->config); + new_volume->set_type(old_volume->type()); + new_volume->set_material_id(old_volume->material_id()); + new_volume->set_transformation(old_volume->get_transformation()); + new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); + std::swap(old_model_object->volumes[old_v.volume_idx], old_model_object->volumes.back()); + old_model_object->delete_volume(old_model_object->volumes.size() - 1); } } } @@ -3963,7 +4016,11 @@ bool Plater::priv::can_reload_from_disk() const for (const SelectedVolume& v : selected_volumes) { const ModelVolume* volume = model.objects[v.object_idx]->volumes[v.volume_idx]; +#if ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION + if (!volume->source.input_file.empty()) +#else if (!volume->source.input_file.empty() && boost::filesystem::exists(volume->source.input_file)) +#endif // ENABLE_RELOAD_FROM_DISK_MISSING_SELECTION paths.push_back(volume->source.input_file); } std::sort(paths.begin(), paths.end());