Fix arrangement of objects larger than the print bed. Issue #2897
This commit is contained in:
parent
2fef16c39a
commit
1c20c4c43d
6 changed files with 56 additions and 33 deletions
|
@ -546,7 +546,12 @@ public:
|
||||||
|
|
||||||
inline explicit _NofitPolyPlacer(const BinType& bin):
|
inline explicit _NofitPolyPlacer(const BinType& bin):
|
||||||
Base(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(const _NofitPolyPlacer&) = default;
|
||||||
_NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default;
|
_NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default;
|
||||||
|
@ -1179,7 +1184,14 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInitialPosition(Item& item) {
|
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;
|
Vertex ci, cb;
|
||||||
auto bbin = sl::boundingBox(bin_);
|
auto bbin = sl::boundingBox(bin_);
|
||||||
|
|
||||||
|
|
|
@ -550,16 +550,7 @@ public:
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safety test: try to pack each item into an empty bin. If it fails
|
this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int acounter = int(store_.size());
|
int acounter = int(store_.size());
|
||||||
std::atomic_flag flg = ATOMIC_FLAG_INIT;
|
std::atomic_flag flg = ATOMIC_FLAG_INIT;
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
TBin&& bin,
|
TBin&& bin,
|
||||||
PConfig&& pconfig = PConfig())
|
PConfig&& pconfig = PConfig())
|
||||||
{
|
{
|
||||||
|
using Placer = PlacementStrategyLike<TPlacer>;
|
||||||
|
|
||||||
store_.clear();
|
store_.clear();
|
||||||
auto total = last-first;
|
auto total = last-first;
|
||||||
|
@ -58,9 +59,11 @@ public:
|
||||||
return i1.area() > i2.area();
|
return i1.area() > i2.area();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
|
||||||
|
|
||||||
std::sort(store_.begin(), store_.end(), sortfunc);
|
std::sort(store_.begin(), store_.end(), sortfunc);
|
||||||
|
|
||||||
PlacementStrategyLike<TPlacer> placer(bin);
|
Placer placer(bin);
|
||||||
placer.configure(pconfig);
|
placer.configure(pconfig);
|
||||||
|
|
||||||
auto it = store_.begin();
|
auto it = store_.begin();
|
||||||
|
|
|
@ -78,16 +78,7 @@ public:
|
||||||
|
|
||||||
auto& cancelled = this->stopcond_;
|
auto& cancelled = this->stopcond_;
|
||||||
|
|
||||||
// Safety test: try to pack each item into an empty bin. If it fails
|
this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = store_.begin();
|
auto it = store_.begin();
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,21 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
template<class Placer, class Container, class Bin, class PCfg>
|
||||||
|
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_;
|
PackGroup packed_bins_;
|
||||||
ProgressFunction progress_ = [](unsigned){};
|
ProgressFunction progress_ = [](unsigned){};
|
||||||
StopCondition stopcond_ = [](){ return false; };
|
StopCondition stopcond_ = [](){ return false; };
|
||||||
|
|
|
@ -350,6 +350,12 @@ public:
|
||||||
m_pck.configure(m_pconf);
|
m_pck.configure(m_pconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoArranger(const TBin & bin,
|
||||||
|
std::function<void(unsigned)> progressind,
|
||||||
|
std::function<bool(void)> stopcond)
|
||||||
|
: AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
|
||||||
|
{}
|
||||||
|
|
||||||
template<class It> inline void operator()(It from, It to) {
|
template<class It> inline void operator()(It from, It to) {
|
||||||
m_rtree.clear();
|
m_rtree.clear();
|
||||||
m_item_count += size_t(to - from);
|
m_item_count += size_t(to - from);
|
||||||
|
@ -553,13 +559,21 @@ BedShapeHint &BedShapeHint::operator=(const BedShapeHint &cpy)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Bin> void remove_large_items(std::vector<Item> &items, Bin &&bin)
|
||||||
|
{
|
||||||
|
auto it = items.begin();
|
||||||
|
while (it != items.end())
|
||||||
|
sl::isInside(it->transformedShape(), bin) ?
|
||||||
|
++it : it = items.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
template<class BinT> // Arrange for arbitrary bin type
|
template<class BinT> // Arrange for arbitrary bin type
|
||||||
void _arrange(
|
void _arrange(
|
||||||
std::vector<Item> & shapes,
|
std::vector<Item> & shapes,
|
||||||
std::vector<Item> & excludes,
|
std::vector<Item> & excludes,
|
||||||
const BinT & bin,
|
const BinT & bin,
|
||||||
coord_t minobjd,
|
coord_t minobjd,
|
||||||
std::function<void(unsigned)> prind,
|
std::function<void(unsigned)> progressfn,
|
||||||
std::function<bool()> stopfn)
|
std::function<bool()> stopfn)
|
||||||
{
|
{
|
||||||
// Integer ceiling the min distance from the bed perimeters
|
// Integer ceiling the min distance from the bed perimeters
|
||||||
|
@ -569,16 +583,13 @@ void _arrange(
|
||||||
auto corrected_bin = bin;
|
auto corrected_bin = bin;
|
||||||
sl::offset(corrected_bin, md);
|
sl::offset(corrected_bin, md);
|
||||||
|
|
||||||
AutoArranger<BinT> arranger{corrected_bin, 0, prind, stopfn};
|
AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
|
||||||
|
|
||||||
auto infl = coord_t(std::ceil(minobjd / 2.0));
|
auto infl = coord_t(std::ceil(minobjd / 2.0));
|
||||||
for (Item& itm : shapes) itm.inflate(infl);
|
for (Item& itm : shapes) itm.inflate(infl);
|
||||||
for (Item& itm : excludes) itm.inflate(infl);
|
for (Item& itm : excludes) itm.inflate(infl);
|
||||||
|
|
||||||
auto it = excludes.begin();
|
remove_large_items(excludes, corrected_bin);
|
||||||
while (it != excludes.end())
|
|
||||||
sl::isInside(it->transformedShape(), corrected_bin) ?
|
|
||||||
++it : it = excludes.erase(it);
|
|
||||||
|
|
||||||
// If there is something on the plate
|
// If there is something on the plate
|
||||||
if (!excludes.empty()) arranger.preload(excludes);
|
if (!excludes.empty()) arranger.preload(excludes);
|
||||||
|
@ -674,7 +685,7 @@ void arrange(ArrangePolygons & arrangables,
|
||||||
_arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn);
|
_arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < items.size(); ++i) {
|
for(size_t i = 0; i < items.size(); ++i) {
|
||||||
clppr::IntPoint tr = items[i].translation();
|
clppr::IntPoint tr = items[i].translation();
|
||||||
|
|
Loading…
Reference in a new issue