From fa2fef9283f79e9f6806340a9169244b249a8ed4 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 15 Dec 2022 12:27:53 +0100 Subject: [PATCH] Optimize csg slicing with large number of positive parts --- src/libslic3r/CSGMesh/SliceCSGMesh.hpp | 36 ++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/CSGMesh/SliceCSGMesh.hpp b/src/libslic3r/CSGMesh/SliceCSGMesh.hpp index f8a7354204..76ca22ec45 100644 --- a/src/libslic3r/CSGMesh/SliceCSGMesh.hpp +++ b/src/libslic3r/CSGMesh/SliceCSGMesh.hpp @@ -4,6 +4,7 @@ #include "CSGMesh.hpp" #include "libslic3r/TriangleMeshSlicer.hpp" #include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/Execution/ExecutionTBB.hpp" namespace Slic3r { namespace csg { @@ -18,6 +19,8 @@ std::vector slice_csgmesh_ex( MeshSlicingParamsEx params_cpy = params; auto trafo = params.trafo; + auto nonempty_indices = reserve_vector(slicegrid.size()); + for (const auto &m : csg) { const indexed_triangle_set *its = csg::get_mesh(m); if (!its) @@ -30,13 +33,18 @@ std::vector slice_csgmesh_ex( assert(slices.size() == slicegrid.size()); + nonempty_indices.clear(); for (size_t i = 0; i < slicegrid.size(); ++i) { + if (get_operation(m) == CSGType::Intersection || !slices[i].empty()) + nonempty_indices.emplace_back(i); + } + + auto mergefn = [&m, &slices, &ret](size_t i){ switch(get_operation(m)) { case CSGType::Union: for (ExPolygon &expoly : slices[i]) ret[i].emplace_back(std::move(expoly)); - ret[i] = union_ex(ret[i]); break; case CSGType::Difference: ret[i] = diff_ex(ret[i], slices[i]); @@ -45,19 +53,25 @@ std::vector slice_csgmesh_ex( ret[i] = intersection_ex(ret[i], slices[i]); break; } - } + }; - for (ExPolygons &slice : ret) { - auto it = std::remove_if(slice.begin(), slice.end(), [](const ExPolygon &p){ - return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON); - }); - - // Hopefully, ExPolygons are moved, not copied to new positions - // and that is cheap for expolygons - slice.erase(it, slice.end()); - } + execution::for_each(ex_tbb, + nonempty_indices.begin(), nonempty_indices.end(), + mergefn, + execution::max_concurrency(ex_tbb)); } + execution::for_each(ex_tbb, ret.begin(), ret.end(), [](ExPolygons &slice) { + auto it = std::remove_if(slice.begin(), slice.end(), [](const ExPolygon &p){ + return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON); + }); + + // Hopefully, ExPolygons are moved, not copied to new positions + // and that is cheap for expolygons + slice.erase(it, slice.end()); + slice = union_ex(slice); + }, execution::max_concurrency(ex_tbb)); + return ret; }