diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index 4ef1fe71d..1a341d691 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -546,7 +546,12 @@ public: inline explicit _NofitPolyPlacer(const BinType& bin): Base(bin), - norm_(std::sqrt(sl::area(bin))) {} + norm_(std::sqrt(sl::area(bin))) + { + // In order to not have items out of bin, it will be shrinked by an + // very little empiric offset value. + // sl::offset(bin_, 1e-5 * norm_); + } _NofitPolyPlacer(const _NofitPolyPlacer&) = default; _NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default; @@ -1179,7 +1184,14 @@ private: } void setInitialPosition(Item& item) { - Box&& bb = item.boundingBox(); + auto sh = item.rawShape(); + sl::translate(sh, item.translation()); + sl::rotate(sh, item.rotation()); + + Box bb = sl::boundingBox(sh); + bb.minCorner() += item.translation(); + bb.maxCorner() += item.translation(); + Vertex ci, cb; auto bbin = sl::boundingBox(bin_); diff --git a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp index f904210aa..30ee7b627 100644 --- a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp +++ b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp @@ -550,16 +550,7 @@ public: return ret; }; - // Safety test: try to pack each item into an empty bin. If it fails - // then it should be removed from the not_packed list - { auto it = store_.begin(); - while (it != store_.end() && !this->stopcond_()) { - Placer p(bin); p.configure(pconfig); - if(!p.pack(*it, rem(it, store_))) { - it = store_.erase(it); - } else it++; - } - } + this->template remove_unpackable_items(store_, bin, pconfig); int acounter = int(store_.size()); std::atomic_flag flg = ATOMIC_FLAG_INIT; diff --git a/src/libnest2d/include/libnest2d/selections/filler.hpp b/src/libnest2d/include/libnest2d/selections/filler.hpp index 19c44bfaa..3b6527d3e 100644 --- a/src/libnest2d/include/libnest2d/selections/filler.hpp +++ b/src/libnest2d/include/libnest2d/selections/filler.hpp @@ -30,7 +30,8 @@ public: TBin&& bin, PConfig&& pconfig = PConfig()) { - + using Placer = PlacementStrategyLike; + store_.clear(); auto total = last-first; store_.reserve(total); @@ -57,10 +58,12 @@ public: auto sortfunc = [](Item& i1, Item& i2) { return i1.area() > i2.area(); }; - + + this->template remove_unpackable_items(store_, bin, pconfig); + std::sort(store_.begin(), store_.end(), sortfunc); - PlacementStrategyLike placer(bin); + Placer placer(bin); placer.configure(pconfig); auto it = store_.begin(); diff --git a/src/libnest2d/include/libnest2d/selections/firstfit.hpp b/src/libnest2d/include/libnest2d/selections/firstfit.hpp index 5585e565d..373e8b618 100644 --- a/src/libnest2d/include/libnest2d/selections/firstfit.hpp +++ b/src/libnest2d/include/libnest2d/selections/firstfit.hpp @@ -77,17 +77,8 @@ public: }; auto& cancelled = this->stopcond_; - - // Safety test: try to pack each item into an empty bin. If it fails - // then it should be removed from the list - { auto it = store_.begin(); - while (it != store_.end() && !cancelled()) { - Placer p(bin); p.configure(pconfig); - if(!p.pack(*it)) { - it = store_.erase(it); - } else it++; - } - } + + this->template remove_unpackable_items(store_, bin, pconfig); auto it = store_.begin(); diff --git a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp index 9ae92fe29..741893078 100644 --- a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp +++ b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp @@ -25,6 +25,21 @@ public: inline void clear() { packed_bins_.clear(); } protected: + + template + void remove_unpackable_items(Container &c, const Bin &bin, const PCfg& pcfg) + { + // Safety test: try to pack each item into an empty bin. If it fails + // then it should be removed from the list + auto it = c.begin(); + while (it != c.end() && !stopcond_()) { + Placer p{bin}; + p.configure(pcfg); + Item cpy{*it}; + if (!p.pack(cpy)) it = c.erase(it); + else it++; + } + } PackGroup packed_bins_; ProgressFunction progress_ = [](unsigned){}; diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 34e07302a..52168c929 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -350,6 +350,12 @@ public: m_pck.configure(m_pconf); } + AutoArranger(const TBin & bin, + std::function progressind, + std::function stopcond) + : AutoArranger{bin, 0 /* no min distance */, progressind, stopcond} + {} + template inline void operator()(It from, It to) { m_rtree.clear(); m_item_count += size_t(to - from); @@ -553,13 +559,21 @@ BedShapeHint &BedShapeHint::operator=(const BedShapeHint &cpy) return *this; } +template void remove_large_items(std::vector &items, Bin &&bin) +{ + auto it = items.begin(); + while (it != items.end()) + sl::isInside(it->transformedShape(), bin) ? + ++it : it = items.erase(it); +} + template // Arrange for arbitrary bin type void _arrange( std::vector & shapes, std::vector & excludes, const BinT & bin, coord_t minobjd, - std::function prind, + std::function progressfn, std::function stopfn) { // Integer ceiling the min distance from the bed perimeters @@ -569,16 +583,13 @@ void _arrange( auto corrected_bin = bin; sl::offset(corrected_bin, md); - AutoArranger arranger{corrected_bin, 0, prind, stopfn}; + AutoArranger arranger{corrected_bin, progressfn, stopfn}; auto infl = coord_t(std::ceil(minobjd / 2.0)); for (Item& itm : shapes) itm.inflate(infl); for (Item& itm : excludes) itm.inflate(infl); - auto it = excludes.begin(); - while (it != excludes.end()) - sl::isInside(it->transformedShape(), corrected_bin) ? - ++it : it = excludes.erase(it); + remove_large_items(excludes, corrected_bin); // If there is something on the plate if (!excludes.empty()) arranger.preload(excludes); @@ -674,7 +685,7 @@ void arrange(ArrangePolygons & arrangables, _arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn); break; } - }; + } for(size_t i = 0; i < items.size(); ++i) { clppr::IntPoint tr = items[i].translation();