mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-30 10:22:00 +08:00
SPE-2488: Fix slow generation of cancel object polygons by performing union operation of polygons incrementally.
When many detailed polygons overlap, performing union over all polygons at once can be quite slow. However, performing the union operation incrementally can be significantly faster in such cases, especially when it is implemented as a parallel reduction.
This commit is contained in:
parent
209d23e0ae
commit
7e163ca6f5
@ -20,6 +20,9 @@
|
||||
#include "libslic3r/Surface.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
#include <oneapi/tbb/blocked_range.h>
|
||||
#include <oneapi/tbb/parallel_reduce.h>
|
||||
|
||||
// #define CLIPPER_UTILS_TIMING
|
||||
|
||||
#ifdef CLIPPER_UTILS_TIMING
|
||||
@ -745,6 +748,8 @@ Slic3r::Polygons union_(const Slic3r::Polygons &subject, const ClipperLib::PolyF
|
||||
{ return to_polygons(clipper_do<ClipperLib::Paths>(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), fillType, ApplySafetyOffset::No)); }
|
||||
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject)
|
||||
{ return _clipper(ClipperLib::ctUnion, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No); }
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygon &subject2)
|
||||
{ return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::SinglePathProvider(subject2.points), ApplySafetyOffset::No); }
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2)
|
||||
{ return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(subject2), ApplySafetyOffset::No); }
|
||||
Slic3r::Polygons union_(Slic3r::Polygons &&subject, const Slic3r::Polygons &subject2) {
|
||||
@ -1012,6 +1017,21 @@ Polygons union_pt_chained_outside_in(const Polygons &subject)
|
||||
return retval;
|
||||
}
|
||||
|
||||
Polygons union_parallel_reduce(const Polygons &subject)
|
||||
{
|
||||
return tbb::parallel_reduce(
|
||||
tbb::blocked_range<size_t>(0, subject.size()), Polygons(),
|
||||
[&subject](tbb::blocked_range<size_t> range, Polygons partial_union) {
|
||||
for (size_t subject_idx = range.begin(); subject_idx < range.end(); ++subject_idx) {
|
||||
partial_union = union_(partial_union, subject[subject_idx]);
|
||||
}
|
||||
return partial_union;
|
||||
},
|
||||
[](const Polygons &a, const Polygons &b) {
|
||||
return union_(a, b);
|
||||
});
|
||||
}
|
||||
|
||||
Polygons simplify_polygons(const Polygons &subject)
|
||||
{
|
||||
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
||||
|
@ -520,6 +520,7 @@ inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject);
|
||||
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject);
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const ClipperLib::PolyFillType fillType);
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygon &subject2);
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2);
|
||||
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::ExPolygon &subject2);
|
||||
// May be used to "heal" unusual models (3DLabPrints etc.) by providing fill_type (pftEvenOdd, pftNonZero, pftPositive, pftNegative).
|
||||
@ -538,6 +539,11 @@ ClipperLib::PolyTree union_pt(const Slic3r::ExPolygons &subject);
|
||||
|
||||
Slic3r::Polygons union_pt_chained_outside_in(const Slic3r::Polygons &subject);
|
||||
|
||||
// Perform union operation on Polygons using parallel reduction to merge Polygons one by one.
|
||||
// When many detailed Polygons overlap, performing union over all Polygons at once can be quite slow.
|
||||
// However, performing the union operation incrementally can be significantly faster in such cases.
|
||||
Slic3r::Polygons union_parallel_reduce(const Slic3r::Polygons &subject);
|
||||
|
||||
ClipperLib::PolyNodes order_nodes(const ClipperLib::PolyNodes &nodes);
|
||||
|
||||
// Implementing generalized loop (foreach) over a list of nodes which can be
|
||||
|
@ -2434,7 +2434,10 @@ Polygons project_mesh(
|
||||
std::vector<Polygons> top, bottom;
|
||||
std::vector<float> zs { -1e10, 1e10 };
|
||||
slice_mesh_slabs(mesh, zs, trafo, &top, &bottom, throw_on_cancel);
|
||||
return union_(top.front(), bottom.back());
|
||||
|
||||
// We typically perform a union operation on a lot of overlapping polygons, which can be slow in some cases.
|
||||
// To address this, we use parallel reduction, which can be significantly faster in such cases.
|
||||
return union_(union_parallel_reduce(top.front()), union_parallel_reduce(bottom.back()));
|
||||
}
|
||||
|
||||
void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *upper, indexed_triangle_set *lower, bool triangulate_caps)
|
||||
|
Loading…
x
Reference in New Issue
Block a user