From 049612022a8233c2757e4f8b418518fd3f91d22e Mon Sep 17 00:00:00 2001 From: harrierpigeon Date: Wed, 5 Aug 2026 03:35:58 -0500 Subject: [PATCH] Perf: avoid unconditional lower-layer polygon copies in support overhang paths (R4, R5) SupportMaterial::detect_overhangs copied lower_layer_polygons per region even without build-plate tilt; hoist the tilted copy out of the region loop and use the original polygons directly when untilted. TreeSupport3D flattened lslices_extrudable to Polygons unconditionally; restore the upstream ExPolygons offset on the untilted path. --- src/libslic3r/Support/SupportMaterial.cpp | 27 ++++++++++++++--------- src/libslic3r/Support/TreeSupport3D.cpp | 7 ++++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/Support/SupportMaterial.cpp b/src/libslic3r/Support/SupportMaterial.cpp index ae5ba5849e..9230807b4b 100644 --- a/src/libslic3r/Support/SupportMaterial.cpp +++ b/src/libslic3r/Support/SupportMaterial.cpp @@ -1475,6 +1475,19 @@ static inline ExPolygons detect_overhangs( } } + // Apply build plate tilt: shift lower layer polygons to simulate tilted gravity. + // This is loop-invariant across regions, so compute it once here. + const Polygons *effective_lower = &lower_layer_polygons; + Polygons tilted_lower; + if (has_tilt) { + tilted_lower = lower_layer_polygons; + const double lh = lower_layer.height; + Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))), + coord_t(scale_(lh * tan(tilt_x_rad)))); + translate(tilted_lower, tilt_shift); + effective_lower = &tilted_lower; + } + for (LayerRegion *layerm : layer.regions()) { // Extrusion width accounts for the roundings of the extrudates. // It is the maximum widh of the extrudate. @@ -1491,17 +1504,9 @@ static inline ExPolygons detect_overhangs( // Overhang polygons for this layer and region. Polygons diff_polygons; Polygons layerm_polygons = to_polygons(layerm->slices.surfaces); - // Apply build plate tilt: shift lower layer polygons to simulate tilted gravity - Polygons effective_lower = lower_layer_polygons; - if (has_tilt) { - const double lh = lower_layer.height; - Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))), - coord_t(scale_(lh * tan(tilt_x_rad)))); - translate(effective_lower, tilt_shift); - } if (lower_layer_offset == 0.f) { // Support everything. - diff_polygons = diff(layerm_polygons, effective_lower); + diff_polygons = diff(layerm_polygons, *effective_lower); if (buildplate_only) { // Don't support overhangs above the top surfaces. // This step is done before the contact surface is calculated by growing the overhang region. @@ -1512,7 +1517,7 @@ static inline ExPolygons detect_overhangs( //FIXME cache the lower layer offset if this layer has multiple regions. diff_polygons = diff(layerm_polygons, - expand(effective_lower, lower_layer_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS)); + expand(*effective_lower, lower_layer_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS)); if (buildplate_only && ! annotations.buildplate_covered[layer_id].empty()) { // Don't support overhangs above the top surfaces. // This step is done before the contact surface is calculated by growing the overhang region. @@ -1522,7 +1527,7 @@ static inline ExPolygons detect_overhangs( // Offset the support regions back to a full overhang, restrict them to the full overhang. // This is done to increase size of the supporting columns below, as they are calculated by // propagating these contact surfaces downwards. - diff_polygons = diff(intersection(expand(diff_polygons, lower_layer_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS), layerm_polygons), effective_lower); + diff_polygons = diff(intersection(expand(diff_polygons, lower_layer_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS), layerm_polygons), *effective_lower); } //FIXME add user defined filtering here based on minimal area or minimum radius or whatever. diff --git a/src/libslic3r/Support/TreeSupport3D.cpp b/src/libslic3r/Support/TreeSupport3D.cpp index 702815e5bb..66b4338d24 100644 --- a/src/libslic3r/Support/TreeSupport3D.cpp +++ b/src/libslic3r/Support/TreeSupport3D.cpp @@ -260,14 +260,17 @@ static std::vector>> group_me } else lower_layer_offset = scaled(lower_layer.height / tan_threshold); // Apply build plate tilt: shift lower layer polygons to simulate tilted gravity - Polygons lower_src = to_polygons(lower_layer.lslices_extrudable); + Polygons lower_layer_offseted; if (has_tilt) { + Polygons lower_src = to_polygons(lower_layer.lslices_extrudable); const double lh = lower_layer.height; Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))), coord_t(scale_(lh * tan(tilt_x_rad)))); translate(lower_src, tilt_shift); + lower_layer_offseted = offset(lower_src, lower_layer_offset); + } else { + lower_layer_offseted = offset(lower_layer.lslices_extrudable, lower_layer_offset); } - Polygons lower_layer_offseted = offset(lower_src, lower_layer_offset); overhangs = diff(current_layer.lslices_extrudable, lower_layer_offseted); if (lower_layer_offset == 0) { raw_overhangs = overhangs;