Fix for incorrect inside check of fixed items.
libnest2d: Add dispatched overloads for offsetting different shapes.
This commit is contained in:
parent
6ae50a710a
commit
72ed8c034e
3 changed files with 53 additions and 15 deletions
|
@ -71,7 +71,8 @@ template<> inline ClipperLib::cInt& y(PointImpl& p)
|
|||
|
||||
namespace shapelike {
|
||||
|
||||
template<> inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance)
|
||||
template<>
|
||||
inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance, const PolygonTag&)
|
||||
{
|
||||
#define DISABLE_BOOST_OFFSET
|
||||
|
||||
|
@ -123,6 +124,14 @@ template<> inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance)
|
|||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void offset(PathImpl& sh, TCoord<PointImpl> distance, const PathTag&)
|
||||
{
|
||||
PolygonImpl p(std::move(sh));
|
||||
offset(p, distance, PolygonTag());
|
||||
sh = p.Contour;
|
||||
}
|
||||
|
||||
// Tell libnest2d how to make string out of a ClipperPolygon object
|
||||
template<> inline std::string toString(const PolygonImpl& sh)
|
||||
{
|
||||
|
|
|
@ -507,15 +507,13 @@ enum class Formats {
|
|||
namespace shapelike {
|
||||
|
||||
template<class S>
|
||||
inline S create(const TContour<S>& contour,
|
||||
const THolesContainer<S>& holes)
|
||||
inline S create(const TContour<S>& contour, const THolesContainer<S>& holes)
|
||||
{
|
||||
return S(contour, holes);
|
||||
}
|
||||
|
||||
template<class S>
|
||||
inline S create(TContour<S>&& contour,
|
||||
THolesContainer<S>&& holes)
|
||||
inline S create(TContour<S>&& contour, THolesContainer<S>&& holes)
|
||||
{
|
||||
return S(contour, holes);
|
||||
}
|
||||
|
@ -727,11 +725,18 @@ inline void translate(S& /*sh*/, const P& /*offs*/)
|
|||
}
|
||||
|
||||
template<class S>
|
||||
inline void offset(S& /*sh*/, TCoord<TPoint<S>> /*distance*/)
|
||||
inline void offset(S& /*sh*/, TCoord<S> /*distance*/, const PathTag&)
|
||||
{
|
||||
dout() << "The current geometry backend does not support offsetting!\n";
|
||||
}
|
||||
|
||||
template<class S>
|
||||
inline void offset(S& sh, TCoord<S> distance, const PolygonTag&)
|
||||
{
|
||||
offset(contour(sh), distance);
|
||||
for(auto &h : holes(sh)) offset(h, -distance);
|
||||
}
|
||||
|
||||
template<class S>
|
||||
inline std::pair<bool, std::string> isValid(const S& /*sh*/)
|
||||
{
|
||||
|
@ -1228,6 +1233,23 @@ template<class S> inline bool isConvex(const S& sh) // dispatch
|
|||
return isConvex(sh, Tag<S>());
|
||||
}
|
||||
|
||||
template<class Box> inline void offset(Box& bb, TCoord<Box> d, const BoxTag&)
|
||||
{
|
||||
TPoint<Box> md{d, d};
|
||||
bb.minCorner() -= md;
|
||||
bb.maxCorner() += md;
|
||||
}
|
||||
|
||||
template<class C> inline void offset(C& circ, TCoord<C> d, const CircleTag&)
|
||||
{
|
||||
circ.radius(circ.radius() + double(d));
|
||||
}
|
||||
|
||||
// Dispatch function
|
||||
template<class S> inline void offset(S& sh, TCoord<S> d) {
|
||||
offset(sh, d, Tag<S>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define DECLARE_MAIN_TYPES(T) \
|
||||
|
|
|
@ -514,19 +514,30 @@ void _arrange(
|
|||
coord_t minobjd,
|
||||
std::function<void(unsigned)> prind,
|
||||
std::function<bool()> stopfn)
|
||||
{
|
||||
AutoArranger<BinT> arranger{bin, minobjd, prind, stopfn};
|
||||
{
|
||||
// Integer ceiling the min distance from the bed perimeters
|
||||
coord_t md = minobjd - 2 * scaled(0.1 + EPSILON);
|
||||
md = (md % 2) ? md / 2 + 1 : md / 2;
|
||||
|
||||
auto corrected_bin = bin;
|
||||
sl::offset(corrected_bin, md);
|
||||
|
||||
AutoArranger<BinT> arranger{corrected_bin, 0, prind, stopfn};
|
||||
|
||||
auto infl = coord_t(std::ceil(minobjd / 2.0));
|
||||
for (Item& itm : shapes) itm.inflate(infl);
|
||||
for (Item& itm : excludes) itm.inflate(infl);
|
||||
|
||||
auto it = excludes.begin();
|
||||
while (it != excludes.end())
|
||||
sl::isInside(it->transformedShape(), bin) ?
|
||||
sl::isInside(it->transformedShape(), corrected_bin) ?
|
||||
++it : it = excludes.erase(it);
|
||||
|
||||
// If there is something on the plate
|
||||
if(!excludes.empty())
|
||||
{
|
||||
arranger.preload(excludes);
|
||||
auto binbb = sl::boundingBox(bin);
|
||||
auto binbb = sl::boundingBox(corrected_bin);
|
||||
|
||||
// Try to put the first item to the center, as the arranger
|
||||
// will not do this for us.
|
||||
|
@ -548,6 +559,7 @@ void _arrange(
|
|||
for (auto &itm : excludes) inp.emplace_back(itm);
|
||||
|
||||
arranger(inp.begin(), inp.end());
|
||||
for (Item &itm : inp) itm.inflate(-infl);
|
||||
}
|
||||
|
||||
// The final client function for arrangement. A progress indicator and
|
||||
|
@ -594,10 +606,6 @@ void arrange(ArrangePolygons & arrangables,
|
|||
|
||||
for (Item &itm : fixeditems) itm.inflate(scaled(-2. * EPSILON));
|
||||
|
||||
// Integer ceiling the min distance from the bed perimeters
|
||||
coord_t md = min_obj_dist - 2 * scaled(0.1 + EPSILON);
|
||||
md = (md % 2) ? md / 2 + 1 : md / 2;
|
||||
|
||||
auto &cfn = stopcondition;
|
||||
auto &pri = progressind;
|
||||
|
||||
|
@ -605,7 +613,6 @@ void arrange(ArrangePolygons & arrangables,
|
|||
case bsBox: {
|
||||
// Create the arranger for the box shaped bed
|
||||
BoundingBox bbb = bedhint.get_box();
|
||||
bbb.min -= Point{md, md}, bbb.max += Point{md, md};
|
||||
Box binbb{{bbb.min(X), bbb.min(Y)}, {bbb.max(X), bbb.max(Y)}};
|
||||
|
||||
_arrange(items, fixeditems, binbb, min_obj_dist, pri, cfn);
|
||||
|
|
Loading…
Reference in a new issue