From 03021c07349041ffc4d9882eb7779a2848be6095 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 16 May 2023 14:49:53 +0200 Subject: [PATCH] Fix for SPE-1709 Crash on "Set number of instances" for multiple selected objects --- src/slic3r/GUI/Plater.cpp | 48 +++++++++++++++++++++------------------ src/slic3r/GUI/Plater.hpp | 2 +- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 2d473646c..2e22dc0de 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6057,36 +6057,36 @@ void Plater::remove_selected() p->view3D->delete_selected(); } -void Plater::increase_instances(size_t num, int obj_idx, std::optional selection_map) +void Plater::increase_instances(size_t num, int obj_idx, int inst_idx) { if (! can_increase_instances()) { return; } Plater::TakeSnapshot snapshot(this, _L("Increase Instances")); - if (obj_idx < 0) - obj_idx = p->get_selected_object_idx(); - if (obj_idx < 0) { - if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) { - // we need a copy made here because the selection changes at every call of increase_instances() - const Selection::ObjectIdxsToInstanceIdxsMap content = selection_map.has_value() ? *selection_map : p->get_selection().get_content(); - for (const size_t obj_id : obj_idxs) { - increase_instances(1, int(obj_id), content); + obj_idx = p->get_selected_object_idx(); + if (obj_idx < 0) { + // It's a case of increasing per 1 instance, when multiple objects are selected + if (const auto obj_idxs = get_selection().get_object_idxs(); !obj_idxs.empty()) { + // we need a copy made here because the selection changes at every call of increase_instances() + const Selection::ObjectIdxsToInstanceIdxsMap content = p->get_selection().get_content(); + for (const size_t& obj_id : obj_idxs) { + if (auto obj_it = content.find(int(obj_id)); obj_it != content.end()) + increase_instances(1, int(obj_id), *obj_it->second.rbegin()); + } } + return; } - return; } + assert(obj_idx >= 0); ModelObject* model_object = p->model.objects[obj_idx]; - int inst_idx = -1; - if (selection_map.has_value()) { - auto obj_it = selection_map->find(obj_idx); - if (obj_it != selection_map->end() && obj_it->second.size() == 1) - inst_idx = *obj_it->second.begin(); - } - else - inst_idx = p->get_selected_instance_idx(); + if (inst_idx < 0 && get_selected_object_idx() >= 0) { + inst_idx = get_selection().get_instance_idx(); + if (0 > inst_idx || inst_idx >= int(model_object->instances.size())) + inst_idx = -1; + } ModelInstance* model_instance = (inst_idx >= 0) ? model_object->instances[inst_idx] : model_object->instances.back(); bool was_one_instance = model_object->instances.size()==1; @@ -6098,7 +6098,6 @@ void Plater::increase_instances(size_t num, int obj_idx, std::optionalget_transformation(); trafo.set_offset(offset_vec); model_object->add_instance(trafo); -// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec)); } if (p->get_config_bool("autocenter")) @@ -6182,11 +6181,16 @@ void Plater::set_number_of_copies() return; TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num)); - for (const auto obj_idx : obj_idxs) { + // we need a copy made here because the selection changes at every call of increase_instances() + Selection::ObjectIdxsToInstanceIdxsMap content = p->get_selection().get_content(); + + for (const auto& obj_idx : obj_idxs) { ModelObject* model_object = p->model.objects[obj_idx]; const int diff = num - (int)model_object->instances.size(); - if (diff > 0) - increase_instances(diff, int(obj_idx)); + if (diff > 0) { + if (auto obj_it = content.find(int(obj_idx)); obj_it != content.end()) + increase_instances(diff, int(obj_idx), *obj_it->second.rbegin()); + } else if (diff < 0) decrease_instances(-diff, int(obj_idx)); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 035932869..19152a7a5 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -250,7 +250,7 @@ public: void reset_with_confirm(); bool delete_object_from_model(size_t obj_idx); void remove_selected(); - void increase_instances(size_t num = 1, int obj_idx = -1, std::optional selection_map = std::nullopt); + void increase_instances(size_t num = 1, int obj_idx = -1, int inst_idx = -1); void decrease_instances(size_t num = 1, int obj_idx = -1); void set_number_of_copies(); void fill_bed_with_instances();