New approach to big items with calculating the best alignment with other big items.
This commit is contained in:
parent
66d1eb9b9d
commit
c8370b5408
@ -314,8 +314,8 @@ inline RawPoint _Box<RawPoint>::center() const BP2D_NOEXCEPT {
|
|||||||
using Coord = TCoord<RawPoint>;
|
using Coord = TCoord<RawPoint>;
|
||||||
|
|
||||||
RawPoint ret = {
|
RawPoint ret = {
|
||||||
static_cast<Coord>( (getX(minc) + getX(maxc))/2.0 ),
|
static_cast<Coord>( std::round((getX(minc) + getX(maxc))/2.0) ),
|
||||||
static_cast<Coord>( (getY(minc) + getY(maxc))/2.0 )
|
static_cast<Coord>( std::round((getY(minc) + getY(maxc))/2.0) )
|
||||||
};
|
};
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -590,7 +590,8 @@ public:
|
|||||||
[this, &merged_pile](
|
[this, &merged_pile](
|
||||||
Nfp::Shapes<RawShape>& /*pile*/,
|
Nfp::Shapes<RawShape>& /*pile*/,
|
||||||
const Item& item,
|
const Item& item,
|
||||||
double occupied_area, double norm,
|
double occupied_area,
|
||||||
|
double norm,
|
||||||
double /*penality*/)
|
double /*penality*/)
|
||||||
{
|
{
|
||||||
merged_pile.emplace_back(item.transformedShape());
|
merged_pile.emplace_back(item.transformedShape());
|
||||||
|
@ -95,12 +95,16 @@ void toSVG(SVG& svg, const Model& model) {
|
|||||||
|
|
||||||
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
|
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
|
||||||
objfunc(const PointImpl& bincenter,
|
objfunc(const PointImpl& bincenter,
|
||||||
|
double bin_area,
|
||||||
ShapeLike::Shapes<PolygonImpl>& pile, // The currently arranged pile
|
ShapeLike::Shapes<PolygonImpl>& pile, // The currently arranged pile
|
||||||
|
double pile_area,
|
||||||
const Item &item,
|
const Item &item,
|
||||||
double norm // A norming factor for physical dimensions
|
double norm, // A norming factor for physical dimensions
|
||||||
|
std::vector<double>& areacache
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
using pl = PointLike;
|
using pl = PointLike;
|
||||||
|
using sl = ShapeLike;
|
||||||
|
|
||||||
static const double BIG_ITEM_TRESHOLD = 0.2;
|
static const double BIG_ITEM_TRESHOLD = 0.2;
|
||||||
static const double ROUNDNESS_RATIO = 0.5;
|
static const double ROUNDNESS_RATIO = 0.5;
|
||||||
@ -109,10 +113,14 @@ objfunc(const PointImpl& bincenter,
|
|||||||
// We will treat big items (compared to the print bed) differently
|
// We will treat big items (compared to the print bed) differently
|
||||||
NfpPlacer::Pile bigs;
|
NfpPlacer::Pile bigs;
|
||||||
bigs.reserve(pile.size());
|
bigs.reserve(pile.size());
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
if(pile.size() < areacache.size()) areacache.clear();
|
||||||
for(auto& p : pile) {
|
for(auto& p : pile) {
|
||||||
auto pbb = ShapeLike::boundingBox(p);
|
if(idx == areacache.size()) areacache.emplace_back(sl::area(p));
|
||||||
auto na = std::sqrt(pbb.width()*pbb.height())/norm;
|
if(std::sqrt(areacache[idx])/norm > BIG_ITEM_TRESHOLD)
|
||||||
if(na > BIG_ITEM_TRESHOLD) bigs.emplace_back(p);
|
bigs.emplace_back(p);
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Candidate item bounding box
|
// Candidate item bounding box
|
||||||
@ -166,9 +174,28 @@ objfunc(const PointImpl& bincenter,
|
|||||||
// Density is the pack density: how big is the arranged pile
|
// Density is the pack density: how big is the arranged pile
|
||||||
auto density = std::sqrt(fullbb.width()*fullbb.height()) / norm;
|
auto density = std::sqrt(fullbb.width()*fullbb.height()) / norm;
|
||||||
|
|
||||||
// The score is a weighted sum of the distance from pile center
|
auto alignment_score = std::numeric_limits<double>::max();
|
||||||
// and the pile size
|
|
||||||
score = ROUNDNESS_RATIO * dist + DENSITY_RATIO * density;
|
auto& trsh = item.transformedShape();
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
for(auto& p : pile) {
|
||||||
|
|
||||||
|
auto parea = areacache[idx];
|
||||||
|
if(std::sqrt(parea)/norm > BIG_ITEM_TRESHOLD) {
|
||||||
|
auto chull = sl::convexHull(sl::Shapes<PolygonImpl>{p, trsh});
|
||||||
|
auto carea = sl::area(chull);
|
||||||
|
|
||||||
|
auto ascore = carea - (item.area() + parea);
|
||||||
|
ascore = std::sqrt(ascore) / norm;
|
||||||
|
|
||||||
|
if(ascore < alignment_score) alignment_score = ascore;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto C = 0.33;
|
||||||
|
score = C * dist + C * density + C * alignment_score;
|
||||||
|
|
||||||
} else if(itemnormarea < BIG_ITEM_TRESHOLD && bigs.empty()) {
|
} else if(itemnormarea < BIG_ITEM_TRESHOLD && bigs.empty()) {
|
||||||
// If there are no big items, only small, we should consider the
|
// If there are no big items, only small, we should consider the
|
||||||
@ -203,7 +230,7 @@ void fillConfig(PConf& pcfg) {
|
|||||||
|
|
||||||
// The accuracy of optimization.
|
// The accuracy of optimization.
|
||||||
// Goes from 0.0 to 1.0 and scales performance as well
|
// Goes from 0.0 to 1.0 and scales performance as well
|
||||||
pcfg.accuracy = 0.35f;
|
pcfg.accuracy = 0.4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TBin>
|
template<class TBin>
|
||||||
@ -221,18 +248,20 @@ protected:
|
|||||||
|
|
||||||
Packer pck_;
|
Packer pck_;
|
||||||
PConfig pconf_; // Placement configuration
|
PConfig pconf_; // Placement configuration
|
||||||
|
double bin_area_;
|
||||||
|
std::vector<double> areacache_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
_ArrBase(const TBin& bin, Distance dist,
|
_ArrBase(const TBin& bin, Distance dist,
|
||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind):
|
||||||
pck_(bin, dist)
|
pck_(bin, dist), bin_area_(ShapeLike::area<PolygonImpl>(bin))
|
||||||
{
|
{
|
||||||
fillConfig(pconf_);
|
fillConfig(pconf_);
|
||||||
pck_.progressIndicator(progressind);
|
pck_.progressIndicator(progressind);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
|
||||||
|
areacache_.clear();
|
||||||
return pck_.arrangeIndexed(std::forward<Args>(args)...);
|
return pck_.arrangeIndexed(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -245,14 +274,15 @@ public:
|
|||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind):
|
||||||
_ArrBase<Box>(bin, dist, progressind)
|
_ArrBase<Box>(bin, dist, progressind)
|
||||||
{
|
{
|
||||||
pconf_.object_function = [bin] (
|
pconf_.object_function = [this, bin] (
|
||||||
Pile& pile,
|
Pile& pile,
|
||||||
const Item &item,
|
const Item &item,
|
||||||
double /*occupied_area*/,
|
double pile_area,
|
||||||
double norm,
|
double norm,
|
||||||
double penality) {
|
double /*penality*/) {
|
||||||
|
|
||||||
auto result = objfunc(bin.center(), pile, item, norm);
|
auto result = objfunc(bin.center(), bin_area_, pile,
|
||||||
|
pile_area, item, norm, areacache_);
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
auto& fullbb = std::get<1>(result);
|
auto& fullbb = std::get<1>(result);
|
||||||
|
|
||||||
@ -275,15 +305,16 @@ public:
|
|||||||
std::function<void(unsigned)> progressind):
|
std::function<void(unsigned)> progressind):
|
||||||
_ArrBase<PolygonImpl>(bin, dist, progressind)
|
_ArrBase<PolygonImpl>(bin, dist, progressind)
|
||||||
{
|
{
|
||||||
pconf_.object_function = [&bin] (
|
pconf_.object_function = [this, &bin] (
|
||||||
Pile& pile,
|
Pile& pile,
|
||||||
const Item &item,
|
const Item &item,
|
||||||
double /*area*/,
|
double pile_area,
|
||||||
double norm,
|
double norm,
|
||||||
double /*penality*/) {
|
double /*penality*/) {
|
||||||
|
|
||||||
auto binbb = ShapeLike::boundingBox(bin);
|
auto binbb = ShapeLike::boundingBox(bin);
|
||||||
auto result = objfunc(binbb.center(), pile, item, norm);
|
auto result = objfunc(binbb.center(), bin_area_, pile,
|
||||||
|
pile_area, item, norm, areacache_);
|
||||||
double score = std::get<0>(result);
|
double score = std::get<0>(result);
|
||||||
|
|
||||||
pile.emplace_back(item.transformedShape());
|
pile.emplace_back(item.transformedShape());
|
||||||
@ -309,14 +340,15 @@ public:
|
|||||||
AutoArranger(Distance dist, std::function<void(unsigned)> progressind):
|
AutoArranger(Distance dist, std::function<void(unsigned)> progressind):
|
||||||
_ArrBase<Box>(Box(0, 0), dist, progressind)
|
_ArrBase<Box>(Box(0, 0), dist, progressind)
|
||||||
{
|
{
|
||||||
this->pconf_.object_function = [] (
|
this->pconf_.object_function = [this] (
|
||||||
Pile& pile,
|
Pile& pile,
|
||||||
const Item &item,
|
const Item &item,
|
||||||
double /*area*/,
|
double pile_area,
|
||||||
double norm,
|
double norm,
|
||||||
double /*penality*/) {
|
double /*penality*/) {
|
||||||
|
|
||||||
auto result = objfunc({0, 0}, pile, item, norm);
|
auto result = objfunc({0, 0}, 0, pile, pile_area,
|
||||||
|
item, norm, areacache_);
|
||||||
return std::get<0>(result);
|
return std::get<0>(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user