1 #ifndef SELECTION_BOILERPLATE_HPP 2 #define SELECTION_BOILERPLATE_HPP 3 4 #include <atomic> 5 #include <libnest2d/nester.hpp> 6 7 namespace libnest2d { namespace selections { 8 9 template<class RawShape> 10 class SelectionBoilerplate { 11 public: 12 using ShapeType = RawShape; 13 using Item = _Item<RawShape>; 14 using ItemGroup = _ItemGroup<RawShape>; 15 using PackGroup = _PackGroup<RawShape>; 16 getResult() const17 inline const PackGroup& getResult() const { 18 return packed_bins_; 19 } 20 lastPackedBinId() const21 inline int lastPackedBinId() const { return last_packed_bin_id_; } 22 progressIndicator(ProgressFunction fn)23 inline void progressIndicator(ProgressFunction fn) { progress_ = fn; } 24 stopCondition(StopCondition cond)25 inline void stopCondition(StopCondition cond) { stopcond_ = cond; } 26 clear()27 inline void clear() { packed_bins_.clear(); } 28 29 protected: 30 31 template<class Placer, class Container, class Bin, class PCfg> remove_unpackable_items(Container & c,const Bin & bin,const PCfg & pcfg)32 void remove_unpackable_items(Container &c, const Bin &bin, const PCfg& pcfg) 33 { 34 // Safety test: try to pack each item into an empty bin. If it fails 35 // then it should be removed from the list 36 auto it = c.begin(); 37 while (it != c.end() && !stopcond_()) { 38 39 // WARNING: The copy of itm needs to be created before Placer. 40 // Placer is working with references and its destructor still 41 // manipulates the item this is why the order of stack creation 42 // matters here. 43 const Item& itm = *it; 44 Item cpy{itm}; 45 46 Placer p{bin}; 47 p.configure(pcfg); 48 if (itm.area() <= 0 || !p.pack(cpy)) { 49 static_cast<Item&>(*it).binId(BIN_ID_UNSET); 50 it = c.erase(it); 51 } 52 else it++; 53 } 54 } 55 56 PackGroup packed_bins_; __anonbc2b59cb0102(unsigned)57 ProgressFunction progress_ = [](unsigned){}; __anonbc2b59cb0202()58 StopCondition stopcond_ = [](){ return false; }; 59 int last_packed_bin_id_ = -1; 60 }; 61 62 } 63 } 64 65 #endif // SELECTION_BOILERPLATE_HPP 66