From 2f160ad8bc397431d1146ecbec757130de2c90dd Mon Sep 17 00:00:00 2001 From: Noisyfox Date: Fri, 8 May 2026 22:54:20 +0800 Subject: [PATCH] Rearrange code a little bit to make it more reusable --- src/libslic3r/CutUtils.cpp | 40 +++++++++--------------------- src/libslic3r/Model.hpp | 18 ++++++++++++++ src/libslic3r/TriangleSelector.hpp | 9 +++++++ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/libslic3r/CutUtils.cpp b/src/libslic3r/CutUtils.cpp index a2cd7583a5..8586b952f3 100644 --- a/src/libslic3r/CutUtils.cpp +++ b/src/libslic3r/CutUtils.cpp @@ -14,17 +14,8 @@ namespace Slic3r { using namespace Geometry; -// Saved painting data for remapping after mesh change. -struct SavedPainting { - indexed_triangle_set its; // Original mesh - TriangleSelector::TriangleSplittingData supported; - TriangleSelector::TriangleSplittingData seam; - TriangleSelector::TriangleSplittingData mmu; - TriangleSelector::TriangleSplittingData fuzzy; -}; - // Remap painting data from saved source to a cut result mesh, and set on a volume. -static void remap_and_set_painting(ModelVolume* vol, const SavedPainting* saved) +static void remap_and_set_painting(ModelVolume* vol, const std::optional& saved) { if (!saved) { return; @@ -34,7 +25,7 @@ static void remap_and_set_painting(ModelVolume* vol, const SavedPainting* saved) FacetsAnnotation& target_facets) { if (src_data.bitstream.empty()) return; - auto result = TriangleSelector::remap_painting(saved->its, src_data, vol->mesh().its, translation_transform(vol->mesh().get_init_shift())); + auto result = TriangleSelector::remap_painting(saved->mesh.its, src_data, vol->mesh().its, translation_transform(vol->mesh().get_init_shift())); if (!result.bitstream.empty()) target_facets.set_data(result); }; @@ -211,7 +202,7 @@ static void process_modifier_cut(ModelVolume* volume, const Transform3d& instanc static void process_solid_part_cut(ModelVolume* volume, const Transform3d& instance_matrix, const Transform3d& cut_matrix, ModelObjectCutAttributes attributes, ModelObject* upper, ModelObject* lower, - const SavedPainting* saved_painting = nullptr) + const std::optional& saved_painting) { // Perform cut TriangleMesh upper_mesh, lower_mesh; @@ -362,20 +353,14 @@ const ModelObjectPtrs& Cut::perform_with_plane() for (ModelVolume* volume : mo->volumes) { // Save painting data before reset_extra_facets() discards it. - // Only for model parts that will be cut (not modifiers/connectors). - std::optional saved_painting; - if (m_attributes.has(ModelObjectCutAttribute::KeepPaint) && volume->is_any_painted() && volume->is_model_part() && !volume->mesh().empty()) { - // Get mesh in cut space (same transform as process_volume_cut applies) - TriangleMesh mesh(volume->mesh()); - const auto volume_matrix = volume->get_matrix(); - mesh.transform(instance_matrix * volume_matrix, true); - SavedPainting sp; - sp.its = std::move(mesh.its); - sp.supported = volume->supported_facets.get_data(); - sp.seam = volume->seam_facets.get_data(); - sp.mmu = volume->mmu_segmentation_facets.get_data(); - sp.fuzzy = volume->fuzzy_skin_facets.get_data(); - saved_painting = std::move(sp); + std::optional saved_painting; + if (m_attributes.has(ModelObjectCutAttribute::KeepPaint)) { + saved_painting = volume->save_painting(); + if (saved_painting) { + // Transform mesh to cut space (same transform as process_volume_cut applies) + const auto volume_matrix = volume->get_matrix(); + saved_painting->mesh.transform(instance_matrix * volume_matrix, true); + } } volume->reset_extra_facets(); @@ -387,8 +372,7 @@ const ModelObjectPtrs& Cut::perform_with_plane() process_connector_cut(volume, instance_matrix, m_cut_matrix, m_attributes, upper, lower, dowels); } else if (!volume->mesh().empty()) - process_solid_part_cut(volume, instance_matrix, m_cut_matrix, m_attributes, upper, lower, - saved_painting ? &*saved_painting : nullptr); + process_solid_part_cut(volume, instance_matrix, m_cut_matrix, m_attributes, upper, lower, saved_painting); } // Post-process cut parts diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 0de76dbef4..ccc0760097 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -878,6 +878,24 @@ public: // List of mesh facets painted for fuzzy skin. FacetsAnnotation fuzzy_skin_facets; + // Save painting data before reset_extra_facets() discards it. + // Used for replacing mesh without losing painting data. + // Only for model parts (not modifiers/connectors). + std::optional save_painting() const + { + if (is_any_painted() && is_model_part() && !mesh().empty()) { + TriangleSelector::SavedPainting sp; + sp.mesh = mesh(); + sp.supported = supported_facets.get_data(); + sp.seam = seam_facets.get_data(); + sp.mmu = mmu_segmentation_facets.get_data(); + sp.fuzzy = fuzzy_skin_facets.get_data(); + return sp; + } + + return {}; + } + // BBS: quick access for volume extruders, 1 based mutable std::vector mmuseg_extruders; mutable Timestamp mmuseg_ts; diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 8f02c7d717..412c9fb9b1 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -372,6 +372,15 @@ public: // The operation may merge split triangles if they are being assigned the same color. void seed_fill_apply_on_triangles(EnforcerBlockerType new_state); + // Saved painting data for remapping after mesh change. + struct SavedPainting { + TriangleMesh mesh; // Original mesh + TriangleSplittingData supported; + TriangleSplittingData seam; + TriangleSplittingData mmu; + TriangleSplittingData fuzzy; + }; + // Remap painting data from source mesh to target mesh using spatial mapping. // `target_transform` should transform the target mesh into source's coordinate space. static TriangleSplittingData remap_painting(