Abort semantics added.
Signed-off-by: tamasmeszaros <meszaros.q@gmail.com>
This commit is contained in:
@@ -640,6 +640,7 @@ public:
|
||||
|
||||
// The progress function will be called with the number of placed items
|
||||
using ProgressFunction = std::function<void(unsigned)>;
|
||||
using StopCondition = std::function<bool(void)>;
|
||||
|
||||
/**
|
||||
* A wrapper interface (trait) class for any selections strategy provider.
|
||||
@@ -674,6 +675,8 @@ public:
|
||||
*/
|
||||
void progressIndicator(ProgressFunction fn) { impl_.progressIndicator(fn); }
|
||||
|
||||
void stopCondition(StopCondition cond) { impl_.stopCondition(cond); }
|
||||
|
||||
/**
|
||||
* \brief A method to start the calculation on the input sequence.
|
||||
*
|
||||
@@ -864,6 +867,11 @@ public:
|
||||
selector_.progressIndicator(func); return *this;
|
||||
}
|
||||
|
||||
/// Set a predicate to tell when to abort nesting.
|
||||
inline Nester& stopCondition(StopCondition fn) {
|
||||
selector_.stopCondition(fn); return *this;
|
||||
}
|
||||
|
||||
inline PackGroup lastResult() {
|
||||
PackGroup ret;
|
||||
for(size_t i = 0; i < selector_.binCount(); i++) {
|
||||
|
||||
@@ -551,7 +551,7 @@ public:
|
||||
// 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()) {
|
||||
while (it != store_.end() && !this->stopcond_()) {
|
||||
Placer p(bin); p.configure(pconfig);
|
||||
if(!p.pack(*it, rem(it, store_))) {
|
||||
it = store_.erase(it);
|
||||
@@ -592,9 +592,11 @@ public:
|
||||
|
||||
bool do_pairs = config_.try_pairs;
|
||||
bool do_triplets = config_.try_triplets;
|
||||
StopCondition stopcond = this->stopcond_;
|
||||
|
||||
// The DJD heuristic algorithm itself:
|
||||
auto packjob = [INITIAL_FILL_AREA, bin_area, w, do_triplets, do_pairs,
|
||||
stopcond,
|
||||
&tryOneByOne,
|
||||
&tryGroupsOfTwo,
|
||||
&tryGroupsOfThree,
|
||||
@@ -606,12 +608,12 @@ public:
|
||||
double waste = .0;
|
||||
bool lasttry = false;
|
||||
|
||||
while(!not_packed.empty()) {
|
||||
while(!not_packed.empty() && !stopcond()) {
|
||||
|
||||
{// Fill the bin up to INITIAL_FILL_PROPORTION of its capacity
|
||||
auto it = not_packed.begin();
|
||||
|
||||
while(it != not_packed.end() &&
|
||||
while(it != not_packed.end() && !stopcond() &&
|
||||
filled_area < INITIAL_FILL_AREA)
|
||||
{
|
||||
if(placer.pack(*it, rem(it, not_packed))) {
|
||||
@@ -623,14 +625,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// try pieses one by one
|
||||
// try pieces one by one
|
||||
while(tryOneByOne(placer, not_packed, waste, free_area,
|
||||
filled_area)) {
|
||||
waste = 0; lasttry = false;
|
||||
makeProgress(placer, idx, 1);
|
||||
}
|
||||
|
||||
// try groups of 2 pieses
|
||||
// try groups of 2 pieces
|
||||
while(do_pairs &&
|
||||
tryGroupsOfTwo(placer, not_packed, waste, free_area,
|
||||
filled_area)) {
|
||||
@@ -638,7 +640,7 @@ public:
|
||||
makeProgress(placer, idx, 2);
|
||||
}
|
||||
|
||||
// try groups of 3 pieses
|
||||
// try groups of 3 pieces
|
||||
while(do_triplets &&
|
||||
tryGroupsOfThree(placer, not_packed, waste, free_area,
|
||||
filled_area)) {
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
placer.configure(pconfig);
|
||||
|
||||
auto it = store_.begin();
|
||||
while(it != store_.end()) {
|
||||
while(it != store_.end() && !this->stopcond_()) {
|
||||
if(!placer.pack(*it, {std::next(it), store_.end()})) {
|
||||
if(packed_bins_.back().empty()) ++it;
|
||||
placer.clearItems();
|
||||
|
||||
@@ -56,10 +56,12 @@ public:
|
||||
this->progress_(static_cast<unsigned>(--total));
|
||||
};
|
||||
|
||||
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()) {
|
||||
while (it != store_.end() && !cancelled()) {
|
||||
Placer p(bin); p.configure(pconfig);
|
||||
if(!p.pack(*it)) {
|
||||
it = store_.erase(it);
|
||||
@@ -67,13 +69,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto it = store_.begin();
|
||||
|
||||
while(it != store_.end()) {
|
||||
while(it != store_.end() && !cancelled()) {
|
||||
bool was_packed = false;
|
||||
size_t j = 0;
|
||||
while(!was_packed) {
|
||||
for(; j < placers.size() && !was_packed; j++) {
|
||||
while(!was_packed && !cancelled()) {
|
||||
for(; j < placers.size() && !was_packed && !cancelled(); j++) {
|
||||
if((was_packed = placers[j].pack(*it, rem(it, store_) )))
|
||||
makeProgress(placers[j], j);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SELECTION_BOILERPLATE_HPP
|
||||
|
||||
#include "../libnest2d.hpp"
|
||||
#include <atomic>
|
||||
|
||||
namespace libnest2d { namespace selections {
|
||||
|
||||
@@ -25,14 +26,15 @@ public:
|
||||
return packed_bins_[binIndex];
|
||||
}
|
||||
|
||||
inline void progressIndicator(ProgressFunction fn) {
|
||||
progress_ = fn;
|
||||
}
|
||||
inline void progressIndicator(ProgressFunction fn) { progress_ = fn; }
|
||||
|
||||
inline void stopCondition(StopCondition cond) { stopcond_ = cond; }
|
||||
|
||||
protected:
|
||||
|
||||
PackGroup packed_bins_;
|
||||
ProgressFunction progress_ = [](unsigned){};
|
||||
StopCondition stopcond_ = [](){ return false; };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user