ENH: auto-arrange uses inner NFP to simplify fixed_overfit

1. Add inner nfp algo.The final nfp result is inner nfp subtract outer nfp.
2. Leave 5(scaled) room in inflation to allow numeric float eps.

Change-Id: I6be0b205c9811af24a238352b256bf1399ee3716
(cherry picked from commit dbab96efc7bfa16afd9db9607b862886606b0aa0)
This commit is contained in:
miaoxin 2022-12-06 17:10:35 +08:00 committed by Lane.Wei
parent 29e6f71402
commit 9857f7384b
5 changed files with 51 additions and 12 deletions

View file

@ -261,6 +261,8 @@ inline TMultiShape<PolygonImpl> merge(const TMultiShape<PolygonImpl>& shapes)
return Slic3r::union_ex(shapes);
}
inline TMultiShape<PolygonImpl> subtract(const TMultiShape<PolygonImpl> &outerBinNfp, const TMultiShape<PolygonImpl> &shapes) { return Slic3r::diff_ex(outerBinNfp, shapes); }
} // namespace nfp
} // namespace libnest2d

View file

@ -179,6 +179,42 @@ inline TPoint<RawShape> referenceVertex(const RawShape& sh)
return rightmostUpVertex(sh);
}
template<class RawBox, class RawShape, class Ratio = double> inline NfpResult<RawShape> nfpInnerRectBed(const RawBox &bed, const RawShape &other)
{
using Vertex = TPoint<RawShape>;
using Edge = _Segment<Vertex>;
namespace sl = shapelike;
auto sbox = sl::boundingBox(other);
auto sheight = sbox.height();
auto swidth = sbox.width();
Vertex slidingTop = rightmostUpVertex(other);
auto leftOffset = slidingTop.x() - sbox.minCorner().x();
auto rightOffset = slidingTop.x() - sbox.maxCorner().x();
auto topOffset = 0;
auto bottomOffset = sheight;
auto boxWidth = bed.width();
auto boxHeight = bed.height();
auto bedMinx = bed.minCorner().x();
auto bedMiny = bed.minCorner().y();
auto bedMaxx = bed.maxCorner().x();
auto bedMaxy = bed.maxCorner().y();
RawShape innerNfp{{bedMinx + leftOffset, bedMaxy + topOffset},
{bedMaxx + rightOffset, bedMaxy + topOffset},
{bedMaxx + rightOffset, bedMiny + bottomOffset},
{bedMinx + leftOffset, bedMiny + bottomOffset},
{bedMinx + leftOffset, bedMaxy + topOffset}};
if (sheight > boxHeight || swidth > boxWidth) {
return {{}, {0, 0}};
} else {
return {innerNfp, {0, 0}};
}
}
/**
* The "trivial" Cuninghame-Green implementation of NFP for convex polygons.
*

View file

@ -565,7 +565,7 @@ private:
using Shapes = TMultiShape<RawShape>;
Shapes calcnfp(const Item &trsh, Lvl<nfp::NfpLevel::CONVEX_ONLY>)
Shapes calcnfp(const Item &trsh, const Box& bed ,Lvl<nfp::NfpLevel::CONVEX_ONLY>)
{
using namespace nfp;
@ -598,7 +598,8 @@ private:
nfps[n] = subnfp_r.first;
});
return nfp::merge(nfps);
RawShape innerNfp = nfpInnerRectBed(bed, trsh.transformedShape()).first;
return nfp::subtract({innerNfp}, nfps);
}
@ -738,7 +739,7 @@ private:
// it is disjunct from the current merged pile
placeOutsideOfBin(item);
nfps = calcnfp(item, Lvl<MaxNfpLevel::value>());
nfps = calcnfp(item, binbb, Lvl<MaxNfpLevel::value>());
auto iv = item.referenceVertex();