diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 0a8d0f480a..9da5edf6c3 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3225,6 +3225,22 @@ void ObjectList::boolean() Plater::TakeSnapshot snapshot(wxGetApp().plater(), "boolean"); ModelObject* object = (*m_objects)[obj_idxs.front()]; + + const bool keep_painting = wxGetApp().app_config->get_bool("keep_painting"); + std::vector> saved_paintings; + if (keep_painting) { + // Save painting of all the positive parts + saved_paintings.reserve(object->volumes.size()); + for (const ModelVolume* vol : object->volumes) { + if (vol && vol->mesh_ptr() && vol->is_model_part() && vol->is_any_painted()) { + saved_paintings.emplace_back(vol->save_painting()); + if (saved_paintings.back()) { + saved_paintings.back()->mesh.transform(vol->get_matrix(), true); + } + } + } + } + TriangleMesh mesh = Plater::combine_mesh_fff(*object, -1, [this](const std::string& msg) {return wxGetApp().notification_manager()->push_plater_error_notification(msg); }); // add mesh to model as a new object, keep the original object's name and config @@ -3236,6 +3252,29 @@ void ObjectList::boolean() new_object->add_instance(); ModelVolume* new_volume = new_object->add_volume(mesh); + // Remap paint + if (keep_painting) { + for (auto& saved_painting : saved_paintings) { + if (saved_painting) { + // For each original painted volume, we need to apply to each instance + // because we merged all instances into one in `combine_mesh_fff` + + // First we save the non-instance-translated mesh + TriangleMesh vols_mesh(std::move(saved_painting->mesh)); + + for (const ModelInstance* i : object->instances) { + // Then for each instance, we apply the paint at the given instance place + saved_painting->mesh = vols_mesh; + saved_painting->mesh.transform(i->get_matrix()); + + // Then paint it + new_volume->restore_painting(saved_painting, true); + } + + } + } + } + // BBS: ensure on bed but no need to ensure locate in the center around origin new_object->ensure_on_bed(); new_object->center_around_origin(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f78cc3f9b7..e95d428248 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -15108,7 +15108,7 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st } if (instance_id == -1) { - TriangleMesh vols_mesh(mesh); + TriangleMesh vols_mesh(std::move(mesh)); mesh = TriangleMesh(); for (const ModelInstance* i : mo.instances) { TriangleMesh m = vols_mesh;