Fixing items partially outside the bed when auto-placing new items.

This commit is contained in:
tamasmeszaros 2019-01-23 16:35:21 +01:00
parent 22ffb93ee5
commit 6819c506d8
5 changed files with 65 additions and 44 deletions

View file

@ -113,6 +113,7 @@ template<> struct CountourType<PolygonImpl> {
template<> struct ShapeTag<PolygonImpl> { using Type = PolygonTag; }; template<> struct ShapeTag<PolygonImpl> { using Type = PolygonTag; };
template<> struct ShapeTag<PathImpl> { using Type = PathTag; }; template<> struct ShapeTag<PathImpl> { using Type = PathTag; };
template<> struct ShapeTag<PointImpl> { using Type = PointTag; };
template<> struct ShapeTag<TMultiShape<PolygonImpl>> { template<> struct ShapeTag<TMultiShape<PolygonImpl>> {
using Type = MultiPolygonTag; using Type = MultiPolygonTag;

View file

@ -69,12 +69,14 @@ struct PointPair {
RawPoint p2; RawPoint p2;
}; };
struct PointTag {};
struct PolygonTag {}; struct PolygonTag {};
struct PathTag {}; struct PathTag {};
struct MultiPolygonTag {}; struct MultiPolygonTag {};
struct BoxTag {}; struct BoxTag {};
struct CircleTag {}; struct CircleTag {};
/// Meta-functions to derive the tags
template<class Shape> struct ShapeTag { using Type = typename Shape::Tag; }; template<class Shape> struct ShapeTag { using Type = typename Shape::Tag; };
template<class S> using Tag = typename ShapeTag<remove_cvref_t<S>>::Type; template<class S> using Tag = typename ShapeTag<remove_cvref_t<S>>::Type;
@ -131,7 +133,7 @@ public:
_Circle(const RawPoint& center, double r): center_(center), radius_(r) {} _Circle(const RawPoint& center, double r): center_(center), radius_(r) {}
inline const RawPoint& center() const BP2D_NOEXCEPT { return center_; } inline const RawPoint& center() const BP2D_NOEXCEPT { return center_; }
inline const void center(const RawPoint& c) { center_ = c; } inline void center(const RawPoint& c) { center_ = c; }
inline double radius() const BP2D_NOEXCEPT { return radius_; } inline double radius() const BP2D_NOEXCEPT { return radius_; }
inline void radius(double r) { radius_ = r; } inline void radius(double r) { radius_ = r; }
@ -518,21 +520,19 @@ inline bool intersects(const RawShape& /*sh*/, const RawShape& /*sh*/)
return false; return false;
} }
template<class RawShape> template<class TGuest, class THost>
inline bool isInside(const TPoint<RawShape>& /*point*/, inline bool isInside(const TGuest&, const THost&,
const RawShape& /*shape*/) const PointTag&, const PolygonTag&) {
{ static_assert(always_false<THost>::value,
static_assert(always_false<RawShape>::value, "shapelike::isInside(point, path) unimplemented!");
"shapelike::isInside(point, shape) unimplemented!");
return false; return false;
} }
template<class RawShape> template<class TGuest, class THost>
inline bool isInside(const RawShape& /*shape*/, inline bool isInside(const TGuest&, const THost&,
const RawShape& /*shape*/) const PolygonTag&, const PolygonTag&) {
{ static_assert(always_false<THost>::value,
static_assert(always_false<RawShape>::value, "shapelike::isInside(shape, shape) unimplemented!");
"shapelike::isInside(shape, shape) unimplemented!");
return false; return false;
} }
@ -651,7 +651,7 @@ template<class RawPath> inline bool isConvex(const RawPath& sh, const PathTag&)
template<class RawShape> template<class RawShape>
inline typename TContour<RawShape>::iterator inline typename TContour<RawShape>::iterator
begin(RawShape& sh, const PolygonTag& t) begin(RawShape& sh, const PolygonTag&)
{ {
return begin(contour(sh), PathTag()); return begin(contour(sh), PathTag());
} }
@ -818,16 +818,16 @@ inline auto convexHull(const RawShape& sh)
return convexHull(sh, Tag<RawShape>()); return convexHull(sh, Tag<RawShape>());
} }
template<class RawShape> template<class TP, class TC>
inline bool isInside(const TPoint<RawShape>& point, inline bool isInside(const TP& point, const TC& circ,
const _Circle<TPoint<RawShape>>& circ) const PointTag&, const CircleTag&)
{ {
return pointlike::distance(point, circ.center()) < circ.radius(); return pointlike::distance(point, circ.center()) < circ.radius();
} }
template<class RawShape> template<class TP, class TB>
inline bool isInside(const TPoint<RawShape>& point, inline bool isInside(const TP& point, const TB& box,
const _Box<TPoint<RawShape>>& box) const PointTag&, const BoxTag&)
{ {
auto px = getX(point); auto px = getX(point);
auto py = getY(point); auto py = getY(point);
@ -839,27 +839,27 @@ inline bool isInside(const TPoint<RawShape>& point,
return px > minx && px < maxx && py > miny && py < maxy; return px > minx && px < maxx && py > miny && py < maxy;
} }
template<class RawShape> template<class RawShape, class TC>
inline bool isInside(const RawShape& sh, inline bool isInside(const RawShape& sh, const TC& circ,
const _Circle<TPoint<RawShape>>& circ) const PolygonTag&, const CircleTag&)
{ {
return std::all_of(cbegin(sh), cend(sh), return std::all_of(cbegin(sh), cend(sh), [&circ](const TPoint<RawShape>& p)
[&circ](const TPoint<RawShape>& p){ {
return isInside<RawShape>(p, circ); return isInside(p, circ, PointTag(), CircleTag());
}); });
} }
template<class RawShape> template<class TB, class TC>
inline bool isInside(const _Box<TPoint<RawShape>>& box, inline bool isInside(const TB& box, const TC& circ,
const _Circle<TPoint<RawShape>>& circ) const BoxTag&, const CircleTag&)
{ {
return isInside<RawShape>(box.minCorner(), circ) && return isInside(box.minCorner(), circ, BoxTag(), CircleTag()) &&
isInside<RawShape>(box.maxCorner(), circ); isInside(box.maxCorner(), circ, BoxTag(), CircleTag());
} }
template<class RawShape> template<class TBGuest, class TBHost>
inline bool isInside(const _Box<TPoint<RawShape>>& ibb, inline bool isInside(const TBGuest& ibb, const TBHost& box,
const _Box<TPoint<RawShape>>& box) const BoxTag&, const BoxTag&)
{ {
auto iminX = getX(ibb.minCorner()); auto iminX = getX(ibb.minCorner());
auto imaxX = getX(ibb.maxCorner()); auto imaxX = getX(ibb.maxCorner());
@ -874,6 +874,18 @@ inline bool isInside(const _Box<TPoint<RawShape>>& ibb,
return iminX > minX && imaxX < maxX && iminY > minY && imaxY < maxY; return iminX > minX && imaxX < maxX && iminY > minY && imaxY < maxY;
} }
template<class RawShape, class TB>
inline bool isInside(const RawShape& poly, const TB& box,
const PolygonTag&, const BoxTag&)
{
return isInside(boundingBox(poly), box, BoxTag(), BoxTag());
}
template<class TGuest, class THost>
inline bool isInside(const TGuest& guest, const THost& host) {
return isInside(guest, host, Tag<TGuest>(), Tag<THost>());
}
template<class RawShape> // Potential O(1) implementation may exist template<class RawShape> // Potential O(1) implementation may exist
inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx, inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx,
const PolygonTag&) const PolygonTag&)

View file

@ -482,12 +482,12 @@ public:
template<class RawShape> template<class RawShape>
inline bool _Item<RawShape>::isInside(const _Box<TPoint<RawShape>>& box) const { inline bool _Item<RawShape>::isInside(const _Box<TPoint<RawShape>>& box) const {
return sl::isInside<RawShape>(boundingBox(), box); return sl::isInside(boundingBox(), box);
} }
template<class RawShape> inline bool template<class RawShape> inline bool
_Item<RawShape>::isInside(const _Circle<TPoint<RawShape>>& circ) const { _Item<RawShape>::isInside(const _Circle<TPoint<RawShape>>& circ) const {
return sl::isInside<RawShape>(transformedShape(), circ); return sl::isInside(transformedShape(), circ);
} }
template<class RawShape> using _ItemRef = std::reference_wrapper<_Item<RawShape>>; template<class RawShape> using _ItemRef = std::reference_wrapper<_Item<RawShape>>;

View file

@ -916,8 +916,8 @@ private:
if(config_.alignment == Config::Alignment::DONT_ALIGN) if(config_.alignment == Config::Alignment::DONT_ALIGN)
ins_check = [&binbb, norm](const Box& fullbb) { ins_check = [&binbb, norm](const Box& fullbb) {
double ret = 0; double ret = 0;
if(sl::isInside<RawShape>(fullbb, binbb)) if(!sl::isInside(fullbb, binbb))
ret += norm*norm; ret += norm;
return ret; return ret;
}; };
else else
@ -958,9 +958,10 @@ private:
ecache[opt.nfpidx].coords(opt.hidx, opt.relpos); ecache[opt.nfpidx].coords(opt.hidx, opt.relpos);
}; };
auto boundaryCheck = auto alignment = config_.alignment;
[&merged_pile, &getNfpPoint, &item, &bin, &iv, &startpos]
(const Optimum& o) auto boundaryCheck = [alignment, &merged_pile, &getNfpPoint,
&item, &bin, &iv, &startpos] (const Optimum& o)
{ {
auto v = getNfpPoint(o); auto v = getNfpPoint(o);
auto d = v - iv; auto d = v - iv;
@ -971,7 +972,12 @@ private:
auto chull = sl::convexHull(merged_pile); auto chull = sl::convexHull(merged_pile);
merged_pile.pop_back(); merged_pile.pop_back();
return overfit(chull, bin); double miss = 0;
if(alignment == Config::Alignment::DONT_ALIGN)
miss = sl::isInside(chull, bin) ? -1.0 : 1.0;
else miss = overfit(chull, bin);
return miss;
}; };
Optimum optimum(0, 0); Optimum optimum(0, 0);

View file

@ -356,13 +356,15 @@ inline double area(const PolygonImpl& shape, const PolygonTag&)
#endif #endif
template<> template<>
inline bool isInside(const PointImpl& point, const PolygonImpl& shape) inline bool isInside(const PointImpl& point, const PolygonImpl& shape,
const PointTag&, const PolygonTag&)
{ {
return boost::geometry::within(point, shape); return boost::geometry::within(point, shape);
} }
template<> template<>
inline bool isInside(const PolygonImpl& sh1, const PolygonImpl& sh2) inline bool isInside(const PolygonImpl& sh1, const PolygonImpl& sh2,
const PolygonTag&, const PolygonTag&)
{ {
return boost::geometry::within(sh1, sh2); return boost::geometry::within(sh1, sh2);
} }