From d132ad2d9d1a69016c142906fa8ee91593a68c04 Mon Sep 17 00:00:00 2001 From: wintergua Date: Wed, 7 Jun 2023 16:15:23 +0800 Subject: [PATCH] =?UTF-8?q?ENH:=20improving=20the=20efficiency=20of=20?= =?UTF-8?q?=E2=80=9CgroupingVolumesForBrim=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tbb parallelization is used to improved the efficiency of for_each_volume and for_each_polygon loop JIRA ID: STUDIO-2866 Change-Id: Id5b3a536e3162b148417cbee803bcede3b62a651 (cherry picked from commit 15a6f7ef2f575eaa4b4694ad357d881b39b82f5b) --- src/libslic3r/PrintObjectSlice.cpp | 70 +++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index d92fb2398..35feb6eca 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -486,14 +486,28 @@ bool groupingVolumes(std::vector objSliceByVolume, std::vector groupIndex(objSliceByVolume.size(), -1); double offsetValue = 0.05 / SCALING_FACTOR; + std::vector> osvIndex; for (int i = 0; i != objSliceByVolume.size(); ++i) { for (int j = 0; j != objSliceByVolume[i].slices.size(); ++j) { - objSliceByVolume[i].slices[j] = offset_ex(objSliceByVolume[i].slices[j], offsetValue); - for (ExPolygon& poly_ex : objSliceByVolume[i].slices[j]) - poly_ex.douglas_peucker(resolution); + osvIndex.push_back({ i,j }); } } + tbb::parallel_for(tbb::blocked_range(0, osvIndex.size()), + [&osvIndex, &objSliceByVolume, &offsetValue, &resolution](const tbb::blocked_range& range) { + for (auto k = range.begin(); k != range.end(); ++k) { + for (ExPolygon& poly_ex : objSliceByVolume[osvIndex[k][0]].slices[osvIndex[k][1]]) + poly_ex.douglas_peucker(resolution); + } + }); + + tbb::parallel_for(tbb::blocked_range(0, osvIndex.size()), + [&osvIndex, &objSliceByVolume,&offsetValue, &resolution](const tbb::blocked_range& range) { + for (auto k = range.begin(); k != range.end(); ++k) { + objSliceByVolume[osvIndex[k][0]].slices[osvIndex[k][1]] = offset_ex(objSliceByVolume[osvIndex[k][0]].slices[osvIndex[k][1]], offsetValue); + } + }); + for (int i = 0; i != objSliceByVolume.size(); ++i) { if (groupIndex[i] < 0) { groupIndex[i] = i; @@ -578,27 +592,43 @@ void applyNegtiveVolumes(ModelVolumePtrs model_volumes, const std::vector& gvss, ExPolygons eps) +void reGroupingLayerPolygons(std::vector& gvss, ExPolygons &eps, double resolution) { std::vector epsIndex; epsIndex.resize(eps.size(), -1); - for (int ie = 0; ie != eps.size(); ie++) { - if (eps[ie].area() <= 0) - continue; - double minArea = eps[ie].area(); - for (int iv = 0; iv != gvss.size(); iv++) { - auto clipedExPolys = diff_ex(eps[ie], gvss[iv].slices); - double area = 0; - for (const auto& ce : clipedExPolys) { - area += ce.area(); - } - if (area < minArea) { - minArea = area; - epsIndex[ie] = iv; - } - } + + auto gvssc = gvss; + auto epsc = eps; + + for (ExPolygon& poly_ex : epsc) + poly_ex.douglas_peucker(resolution); + + for (int i = 0; i != gvssc.size(); ++i) { + for (ExPolygon& poly_ex : gvssc[i].slices) + poly_ex.douglas_peucker(resolution); } + tbb::parallel_for(tbb::blocked_range(0, epsc.size()), + [&epsc, &gvssc, &epsIndex](const tbb::blocked_range& range) { + for (auto ie = range.begin(); ie != range.end(); ++ie) { + if (epsc[ie].area() <= 0) + continue; + + double minArea = epsc[ie].area(); + for (int iv = 0; iv != gvssc.size(); iv++) { + auto clipedExPolys = diff_ex(epsc[ie], gvssc[iv].slices); + double area = 0; + for (const auto& ce : clipedExPolys) { + area += ce.area(); + } + if (area < minArea) { + minArea = area; + epsIndex[ie] = iv; + } + } + } + }); + for (int iv = 0; iv != gvss.size(); iv++) gvss[iv].slices.clear(); @@ -734,7 +764,7 @@ void groupingVolumesForBrim(PrintObject* object, LayerPtrs& layers, int firstLay applyNegtiveVolumes(object->model_object()->volumes, object->firstLayerObjSliceMod(), object->firstLayerObjGroupsMod(), scaled_resolution); // BBS: the actual first layer slices stored in layers are re-sorted by volume group and will be used to generate brim - reGroupingLayerPolygons(object->firstLayerObjGroupsMod(), layers.front()->lslices); + reGroupingLayerPolygons(object->firstLayerObjGroupsMod(), layers.front()->lslices, scaled_resolution); } // Called by make_perimeters()