From 963f96b31fbd123350a52b94f617188768adb466 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 15 Jan 2025 15:48:06 +0100 Subject: [PATCH] SPE-2630: Fixed CSG operations on meshes splittable to parts with inward-facing normals (#13786) --- src/libslic3r/CSGMesh/ModelToCSGMesh.hpp | 35 ++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/CSGMesh/ModelToCSGMesh.hpp b/src/libslic3r/CSGMesh/ModelToCSGMesh.hpp index 8e51898320..7e639cca07 100644 --- a/src/libslic3r/CSGMesh/ModelToCSGMesh.hpp +++ b/src/libslic3r/CSGMesh/ModelToCSGMesh.hpp @@ -45,18 +45,31 @@ void model_to_csgmesh(const ModelObject &mo, part_begin.stack_operation = CSGStackOp::Push; *out = std::move(part_begin); ++out; + + // Collect partial meshes and keep outward and inward facing meshes separately. + std::vector meshes_union; + std::vector meshes_difference; + its_split(vol->mesh().its, SplitOutputFn{[&meshes_union, &meshes_difference](indexed_triangle_set &&its) { + if (its.empty()) + return; + if (its_volume(its) >= 0.f) + meshes_union.emplace_back(std::move(its)); + else { + its_flip_triangles(its); + meshes_difference.emplace_back(std::move(its)); + } + }}); - its_split(vol->mesh().its, SplitOutputFn{[&out, &vol, &trafo](indexed_triangle_set &&its) { - if (its.empty()) - return; - - CSGPart part{std::make_unique(std::move(its)), - CSGType::Union, - (trafo * vol->get_matrix()).cast()}; - - *out = std::move(part); - ++out; - }}); + // Add the operation for each of the partial mesh (outward-facing normals go first). + for (auto* meshes : { &meshes_union, &meshes_difference}) { + for (indexed_triangle_set& its : *meshes) { + CSGPart part{ std::make_unique(std::move(its)), + meshes == &meshes_union ? CSGType::Union : CSGType::Difference, + (trafo * vol->get_matrix()).cast() }; + *out = std::move(part); + ++out; + } + } CSGPart part_end{{}}; part_end.stack_operation = CSGStackOp::Pop;