mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 17:45:58 +08:00
Optimize csg slicing with large number of positive parts
This commit is contained in:
parent
473c8a26a4
commit
fa2fef9283
@ -4,6 +4,7 @@
|
|||||||
#include "CSGMesh.hpp"
|
#include "CSGMesh.hpp"
|
||||||
#include "libslic3r/TriangleMeshSlicer.hpp"
|
#include "libslic3r/TriangleMeshSlicer.hpp"
|
||||||
#include "libslic3r/ClipperUtils.hpp"
|
#include "libslic3r/ClipperUtils.hpp"
|
||||||
|
#include "libslic3r/Execution/ExecutionTBB.hpp"
|
||||||
|
|
||||||
namespace Slic3r { namespace csg {
|
namespace Slic3r { namespace csg {
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ std::vector<ExPolygons> slice_csgmesh_ex(
|
|||||||
|
|
||||||
MeshSlicingParamsEx params_cpy = params;
|
MeshSlicingParamsEx params_cpy = params;
|
||||||
auto trafo = params.trafo;
|
auto trafo = params.trafo;
|
||||||
|
auto nonempty_indices = reserve_vector<size_t>(slicegrid.size());
|
||||||
|
|
||||||
for (const auto &m : csg) {
|
for (const auto &m : csg) {
|
||||||
const indexed_triangle_set *its = csg::get_mesh(m);
|
const indexed_triangle_set *its = csg::get_mesh(m);
|
||||||
if (!its)
|
if (!its)
|
||||||
@ -30,13 +33,18 @@ std::vector<ExPolygons> slice_csgmesh_ex(
|
|||||||
|
|
||||||
assert(slices.size() == slicegrid.size());
|
assert(slices.size() == slicegrid.size());
|
||||||
|
|
||||||
|
nonempty_indices.clear();
|
||||||
for (size_t i = 0; i < slicegrid.size(); ++i) {
|
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)) {
|
switch(get_operation(m)) {
|
||||||
case CSGType::Union:
|
case CSGType::Union:
|
||||||
for (ExPolygon &expoly : slices[i])
|
for (ExPolygon &expoly : slices[i])
|
||||||
ret[i].emplace_back(std::move(expoly));
|
ret[i].emplace_back(std::move(expoly));
|
||||||
|
|
||||||
ret[i] = union_ex(ret[i]);
|
|
||||||
break;
|
break;
|
||||||
case CSGType::Difference:
|
case CSGType::Difference:
|
||||||
ret[i] = diff_ex(ret[i], slices[i]);
|
ret[i] = diff_ex(ret[i], slices[i]);
|
||||||
@ -45,19 +53,25 @@ std::vector<ExPolygons> slice_csgmesh_ex(
|
|||||||
ret[i] = intersection_ex(ret[i], slices[i]);
|
ret[i] = intersection_ex(ret[i], slices[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
for (ExPolygons &slice : ret) {
|
execution::for_each(ex_tbb,
|
||||||
auto it = std::remove_if(slice.begin(), slice.end(), [](const ExPolygon &p){
|
nonempty_indices.begin(), nonempty_indices.end(),
|
||||||
return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON);
|
mergefn,
|
||||||
});
|
execution::max_concurrency(ex_tbb));
|
||||||
|
|
||||||
// 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, 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user