Optimize csg slicing with large number of positive parts

This commit is contained in:
tamasmeszaros 2022-12-15 12:27:53 +01:00
parent 473c8a26a4
commit fa2fef9283

View File

@ -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<ExPolygons> slice_csgmesh_ex(
MeshSlicingParamsEx params_cpy = params;
auto trafo = params.trafo;
auto nonempty_indices = reserve_vector<size_t>(slicegrid.size());
for (const auto &m : csg) {
const indexed_triangle_set *its = csg::get_mesh(m);
if (!its)
@ -30,13 +33,18 @@ std::vector<ExPolygons> 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,9 +53,15 @@ std::vector<ExPolygons> slice_csgmesh_ex(
ret[i] = intersection_ex(ret[i], slices[i]);
break;
}
};
execution::for_each(ex_tbb,
nonempty_indices.begin(), nonempty_indices.end(),
mergefn,
execution::max_concurrency(ex_tbb));
}
for (ExPolygons &slice : ret) {
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);
});
@ -55,8 +69,8 @@ std::vector<ExPolygons> slice_csgmesh_ex(
// 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;
}