diff --git a/src/libnest2d/include/libnest2d/nester.hpp b/src/libnest2d/include/libnest2d/nester.hpp index 2f207d526..59477b4f1 100644 --- a/src/libnest2d/include/libnest2d/nester.hpp +++ b/src/libnest2d/include/libnest2d/nester.hpp @@ -741,6 +741,10 @@ public: return impl_.getResult(); } + inline int lastPackedBinId() const { + return impl_.lastPackedBinId(); + } + void clear() { impl_.clear(); } }; @@ -862,6 +866,10 @@ public: { return selector_.getResult(); } + + inline int lastPackedBinId() const { + return selector_.lastPackedBinId(); + } }; } diff --git a/src/libnest2d/include/libnest2d/selections/firstfit.hpp b/src/libnest2d/include/libnest2d/selections/firstfit.hpp index 373e8b618..e50fd7009 100644 --- a/src/libnest2d/include/libnest2d/selections/firstfit.hpp +++ b/src/libnest2d/include/libnest2d/selections/firstfit.hpp @@ -71,8 +71,9 @@ public: std::sort(store_.begin(), store_.end(), sortfunc); auto total = last-first; - auto makeProgress = [this, &total](Placer& placer, size_t idx) { - packed_bins_[idx] = placer.getItems(); + auto makeProgress = [this, &total](Placer& placer, size_t bin_idx) { + packed_bins_[bin_idx] = placer.getItems(); + this->last_packed_bin_id_ = int(bin_idx); this->progress_(static_cast(--total)); }; diff --git a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp index e96378296..431159641 100644 --- a/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp +++ b/src/libnest2d/include/libnest2d/selections/selection_boilerplate.hpp @@ -18,6 +18,8 @@ public: return packed_bins_; } + inline int lastPackedBinId() const { return last_packed_bin_id_; } + inline void progressIndicator(ProgressFunction fn) { progress_ = fn; } inline void stopCondition(StopCondition cond) { stopcond_ = cond; } @@ -54,6 +56,7 @@ protected: PackGroup packed_bins_; ProgressFunction progress_ = [](unsigned){}; StopCondition stopcond_ = [](){ return false; }; + int last_packed_bin_id_ = -1; }; } diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 1036844d7..705e213e3 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -309,7 +309,7 @@ protected: public: AutoArranger(const TBin & bin, const ArrangeParams ¶ms, - std::function progressind, + std::function progressind, std::function stopcond) : m_pck(bin, params.min_obj_distance) , m_bin(bin) @@ -347,10 +347,27 @@ public: }; m_pconf.object_function = get_objfn(); + + auto on_packed = params.on_packed; - if (progressind) m_pck.progressIndicator([this, &progressind](unsigned rem) { - progressind(rem, m_pck.lastResult().size() - 1); + if (progressind || on_packed) + m_pck.progressIndicator([this, progressind, on_packed](unsigned rem) { + + if (progressind) + progressind(rem); + + if (on_packed) { + int last_bed = m_pck.lastPackedBinId(); + if (last_bed >= 0) { + Item &last_packed = m_pck.lastResult()[last_bed].back(); + ArrangePolygon ap; + ap.bed_idx = last_packed.binId(); + ap.priority = last_packed.priority(); + on_packed(ap); + } + } }); + if (stopcond) m_pck.stopCondition(stopcond); m_pck.configure(m_pconf); @@ -464,7 +481,7 @@ void _arrange( std::vector & excludes, const BinT & bin, const ArrangeParams ¶ms, - std::function progressfn, + std::function progressfn, std::function stopfn) { // Integer ceiling the min distance from the bed perimeters diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 69511e7ec..ec46da8d3 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -83,8 +83,9 @@ struct ArrangeParams { /// Progress indicator callback called when an object gets packed. /// The unsigned argument is the number of items remaining to pack. - /// Second is the current bed idx being filled. - std::function progressind; + std::function progressind; + + std::function on_packed; /// A predicate returning true if abort is needed. std::function stopcondition; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 7af0b4703..7a8c21365 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -158,14 +158,14 @@ void ArrangeJob::process() params.stopcondition = [this]() { return was_canceled(); }; try { - params.progressind = [this, count](unsigned st, unsigned) { + params.progressind = [this, count](unsigned st) { st += m_unprintable.size(); if (st > 0) update_status(int(count - st), arrangestr); }; arrangement::arrange(m_selected, m_unselected, bedpts, params); - params.progressind = [this, count](unsigned st, unsigned) { + params.progressind = [this, count](unsigned st) { if (st > 0) update_status(int(count - st), arrangestr); }; diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 9c959ff16..dc91ca9e3 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -90,17 +90,20 @@ void FillBedJob::process() params.min_obj_distance = scaled(settings.distance); params.allow_rotations = settings.enable_rotation; - unsigned curr_bed = 0; - params.stopcondition = [this, &curr_bed]() { - return was_canceled() || curr_bed > 0; + bool do_stop = false; + params.stopcondition = [this, &do_stop]() { + return was_canceled() || do_stop; }; - params.progressind = [this, &curr_bed](unsigned st, unsigned bed) { - curr_bed = bed; + params.progressind = [this](unsigned st) { if (st > 0) update_status(int(m_status_range - st), _(L("Filling bed"))); }; + params.on_packed = [&do_stop] (const ArrangePolygon &ap) { + do_stop = ap.bed_idx > 0 && ap.priority == 0; + }; + arrangement::arrange(m_selected, m_unselected, m_bedpts, params); // finalize just here. @@ -119,7 +122,7 @@ void FillBedJob::finalize() size_t inst_cnt = model_object->instances.size(); for (ArrangePolygon &ap : m_selected) { - if (ap.priority != 0 || !(ap.bed_idx == arrangement::UNARRANGED || ap.bed_idx > 0)) + if (ap.bed_idx != arrangement::UNARRANGED && (ap.priority != 0 || ap.bed_idx == 0)) ap.apply(); }