From bb8cca8999aab90c48cac675e4fb402e9e955abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Tue, 26 Nov 2024 22:41:33 +0100 Subject: [PATCH] Fix arrange after cut (SPE-2583, #13637) The cut arrange updated the Plater without the new objects being on any of the beds. This led to mutliple beds reducing the bed count and activating a previous bed. This in turn ment that get_active_bed was temporarily wrong and the subsequent arrange placed items on a wrong bed. Improve this by explictly setting which bed is going to be used for the arrange and than restoring the originally active bed. If there is just one instance, simply choose the bed the instance is on. If there are more instances, use the active bed for arrange. --- src/slic3r/GUI/Plater.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 28c6a9ced3..8cfe8b42ec 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5532,6 +5532,22 @@ void Plater::toggle_layers_editing(bool enable) void Plater::apply_cut_object_to_model(size_t obj_idx, const ModelObjectPtrs& new_objects) { + const int active_bed{s_multiple_beds.get_active_bed()}; + + const ModelInstancePtrs &instances{model().objects[obj_idx]->instances}; + const ObjectID first_instance_id{instances.front()->id()}; + const std::optional first_instance_bed_index{ + s_multiple_beds.get_inst_map().count(first_instance_id) > 0 ? + std::optional{s_multiple_beds.get_inst_map().at(first_instance_id)} : + std::nullopt + }; + + const auto bed_index{ + instances.size() == 1 && first_instance_bed_index ? + *first_instance_bed_index : + active_bed + }; + model().delete_object(obj_idx); sidebar().obj_list()->delete_object_from_list(obj_idx); @@ -5540,6 +5556,7 @@ void Plater::apply_cut_object_to_model(size_t obj_idx, const ModelObjectPtrs& ne // now process all updates of the 3d scene update(); + // Update InfoItems in ObjectList after update() to use of a correct value of the GLCanvas3D::is_sinking(), // which is updated after a view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH) call for (size_t idx = 0; idx < p->model.objects.size(); idx++) @@ -5551,12 +5568,16 @@ void Plater::apply_cut_object_to_model(size_t obj_idx, const ModelObjectPtrs& ne selection.add_object((unsigned int)(last_id - i), i == 0); const ModelInstance* mi = p->model.objects[last_id - i]->instances.front(); const ObjectID instance_id{mi->id().id}; - s_multiple_beds.set_instance_bed(instance_id, mi->printable, s_multiple_beds.get_active_bed()); + s_multiple_beds.set_instance_bed(instance_id, mi->printable, bed_index); } + s_multiple_beds.inst_map_updated(); + s_multiple_beds.set_active_bed(bed_index); + UIThreadWorker w; arrange(w, ArrangeSelectionMode::CurrentBedSelectionOnly); w.wait_for_idle(); + s_multiple_beds.set_active_bed(active_bed); }