From dc8008bcb80c0b77e4339833693535ec09aa1b08 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 25 Jul 2023 13:32:16 +0200 Subject: [PATCH] Fix failing back-fitting of single selected items when rotations enabled --- src/libslic3r/Arrange/ArrangeImpl.hpp | 52 +++++++++++++------ .../Arrange/Core/NFP/PackStrategyNFP.hpp | 4 +- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/libslic3r/Arrange/ArrangeImpl.hpp b/src/libslic3r/Arrange/ArrangeImpl.hpp index cebc31ac4a..57e9e1f358 100644 --- a/src/libslic3r/Arrange/ArrangeImpl.hpp +++ b/src/libslic3r/Arrange/ArrangeImpl.hpp @@ -216,6 +216,40 @@ inline RectPivots xlpivots_to_rect_pivots(ArrangeSettingsView::XLPivots xlpivot) return rectpivot; } +template +void fill_rotations(const Range &items, + const Bed &bed, + const ArrangeSettingsView &settings) +{ + if (!settings.is_rotation_enabled()) + return; + + for (auto &itm : items) { + // Use the minimum bounding box rotation as a starting point. + auto minbbr = get_min_area_bounding_box_rotation(itm); + std::vector rotations = + {minbbr, + minbbr + PI / 4., minbbr + PI / 2., + minbbr + PI, minbbr + 3 * PI / 4.}; + + // Add the original rotation of the item if minbbr + // is not already the original rotation (zero) + if (std::abs(minbbr) > 0.) + rotations.emplace_back(0.); + + // Also try to find the rotation that fits the item + // into a rectangular bed, given that it cannot fit, + // and there exists a rotation which can fit. + if constexpr (std::is_convertible_v) { + double fitbrot = get_fit_into_bed_rotation(itm, bed); + if (std::abs(fitbrot) > 0.) + rotations.emplace_back(fitbrot); + } + + set_allowed_rotations(itm, rotations); + } +} + // An arranger put together to fulfill all the requirements of PrusaSlicer based // on the supplied ArrangeSettings template @@ -271,23 +305,7 @@ class DefaultArranger: public Arranger { auto & kernel = basekernel; #endif - // Use the minimum bounding box rotation as a starting point. - if (m_settings.is_rotation_enabled()) { - for (auto &itm : items) { - double fit_bed_rot = 0.; - - if constexpr (std::is_convertible_v) - fit_bed_rot = get_fit_into_bed_rotation(itm, bed); - - auto minbbr = get_min_area_bounding_box_rotation(itm); - std::vector rotations = - {minbbr, fit_bed_rot, - minbbr + PI / 4., minbbr + PI / 2., - minbbr + PI, minbbr + 3 * PI / 4.}; - - set_allowed_rotations(itm, rotations); - } - } + fill_rotations(items, bed, m_settings); bool with_wipe_tower = std::any_of(items.begin(), items.end(), [](auto &itm) { diff --git a/src/libslic3r/Arrange/Core/NFP/PackStrategyNFP.hpp b/src/libslic3r/Arrange/Core/NFP/PackStrategyNFP.hpp index c042829dfb..838530505b 100644 --- a/src/libslic3r/Arrange/Core/NFP/PackStrategyNFP.hpp +++ b/src/libslic3r/Arrange/Core/NFP/PackStrategyNFP.hpp @@ -252,14 +252,12 @@ bool pack(Strategy &strategy, if (!nfp.empty()) { score = pick_best_spot_on_nfp(item, nfp, bed, strategy); - cancelled = std::isnan(score) || strategy.stop_condition(); + cancelled = strategy.stop_condition(); if (score > final_score) { final_score = score; final_rot = rot; final_tr = get_translation(item); } - } else { - cancelled = true; } }