From ea5119ec3f89af6334d8ec3723fb87456d5a277d Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Mon, 11 May 2026 15:33:09 +0800 Subject: [PATCH] Remap paint after contour cut (cut with part assigned to other side using right mouse click) --- src/libslic3r/CutUtils.cpp | 19 ++++++++++++++++--- src/libslic3r/CutUtils.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/CutUtils.cpp b/src/libslic3r/CutUtils.cpp index d192a854bb..5899313035 100644 --- a/src/libslic3r/CutUtils.cpp +++ b/src/libslic3r/CutUtils.cpp @@ -454,7 +454,7 @@ static void merge_solid_parts_inside_object(ModelObjectPtrs& objects) } -const ModelObjectPtrs& Cut::perform_by_contour(std::vector parts, int dowels_count) +const ModelObjectPtrs& Cut::perform_by_contour(const ModelObject* src_object, std::vector parts, int dowels_count) { ModelObject* cut_mo = m_model.objects.front(); @@ -469,6 +469,19 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector parts, int dowe lower->name = lower->name + "_B"; } + // Save painting data so we later can remap it. + std::vector> saved_paintings; + if (m_attributes.has(ModelObjectCutAttribute::KeepPaint)) { + const auto instance_matrix = src_object->instances[m_instance]->get_transformation().get_matrix_no_offset(); + for (const auto volume : src_object->volumes) { + saved_paintings.emplace_back(volume->save_painting()); + if (saved_paintings.back()) { + // Transform mesh to cut space (same transform as process_volume_cut applies) + saved_paintings.back()->mesh.transform(instance_matrix * volume->get_matrix(), true); + } + } + } + const size_t cut_parts_cnt = parts.size(); bool has_modifiers = false; @@ -498,7 +511,7 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector parts, int dowe merge_solid_parts_inside_object(cut_object_ptrs); // replace initial objects in model with cut object - finalize(cut_object_ptrs, {}); + finalize(cut_object_ptrs, saved_paintings); } else if (volumes.size() > cut_parts_cnt) { // Means that object is cut with connectors @@ -529,7 +542,7 @@ const ModelObjectPtrs& Cut::perform_by_contour(std::vector parts, int dowe merge_solid_parts_inside_object(cut_object_ptrs); // replace initial objects in model with cut object - finalize(cut_object_ptrs, {}); + finalize(cut_object_ptrs, saved_paintings); // Add Dowel-connectors as separate objects to model if (cut_connectors_obj.size() >= 3) diff --git a/src/libslic3r/CutUtils.hpp b/src/libslic3r/CutUtils.hpp index d7e486beaf..99cdb9cd65 100644 --- a/src/libslic3r/CutUtils.hpp +++ b/src/libslic3r/CutUtils.hpp @@ -56,7 +56,7 @@ public: }; const ModelObjectPtrs& perform_with_plane(); - const ModelObjectPtrs& perform_by_contour(std::vector parts, int dowels_count); + const ModelObjectPtrs& perform_by_contour(const ModelObject* src_object, std::vector parts, int dowels_count); const ModelObjectPtrs& perform_with_groove(const Groove& groove, const Transform3d& rotation_m, bool keep_as_parts = false); }; // namespace Cut diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index da523788b8..f042656ab7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -1908,7 +1908,7 @@ GLGizmoCut3D::PartSelection::PartSelection(const ModelObject* mo, const Transfor // split to parts for (int id = int(volumes.size())-1; id >= 0; id--) if (volumes[id]->is_splittable()) - volumes[id]->split(1, false); // TODO: fix this + volumes[id]->split(1, false); // No need to remap paint here, we do it later in perform_by_contour m_parts.clear(); for (const ModelVolume* volume : volumes) { @@ -3337,7 +3337,7 @@ void GLGizmoCut3D::perform_cut(const Selection& selection) update_object_cut_id(cut_mo->cut_id, attributes, dowels_count); Cut cut(cut_mo, instance_idx, get_cut_matrix(selection), attributes); - const ModelObjectPtrs& new_objects = cut_by_contour ? cut.perform_by_contour(m_part_selection.get_cut_parts(), dowels_count): + const ModelObjectPtrs& new_objects = cut_by_contour ? cut.perform_by_contour(mo, m_part_selection.get_cut_parts(), dowels_count): cut_with_groove ? cut.perform_with_groove(m_groove, m_rotation_m) : cut.perform_with_plane();