Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
libnest2d::placers::_BottomLeftPlacer< RawShape > Class Template Reference

#include <src/libnest2d/include/libnest2d/placers/bottomleftplacer.hpp>

+ Inheritance diagram for libnest2d::placers::_BottomLeftPlacer< RawShape >:
+ Collaboration diagram for libnest2d::placers::_BottomLeftPlacer< RawShape >:

Public Types

enum class  Dir { LEFT , DOWN }
 
using ShapeType = RawShape
 
using Item = _Item< RawShape >
 
using Vertex = TPoint< RawShape >
 
using Segment = _Segment< Vertex >
 
using BinType = _Box< TPoint< RawShape > >
 
using Coord = TCoord< Vertex >
 
using Config = BLConfig< RawShape >
 
using ItemGroup = _ItemGroup< RawShape >
 
using DefaultIter = typename ItemGroup::const_iterator
 

Public Member Functions

 _BottomLeftPlacer (const BinType &bin)
 
template<class Range = ConstItemRange<typename Base::DefaultIter>>
PackResult trypack (Item &item, const Range &=Range())
 
RawShape leftPoly (const Item &item) const
 
RawShape downPoly (const Item &item) const
 
Coord availableSpaceLeft (const Item &item)
 
Coord availableSpaceDown (const Item &item)
 
const BinTypebin () const BP2D_NOEXCEPT
 
void bin (TB &&b)
 
void configure (const Config &config) BP2D_NOEXCEPT
 
bool pack (Item &item, const Range &rem=Range())
 
void preload (const ItemGroup &packeditems)
 
void accept (PackResult &r)
 
void unpackLast ()
 
const ItemGroupgetItems () const
 
void clearItems ()
 
double filledArea () const
 

Protected Member Functions

PackResult _trypack (Item &item)
 
void setInitialPosition (Item &item)
 
ItemGroup itemsInTheWayOf (const Item &item, const Dir dir)
 
Coord availableSpace (const Item &_item, const Dir dir)
 
RawShape toWallPoly (const Item &_item, const Dir dir) const
 

Static Protected Member Functions

template<class C = Coord>
static enable_if_t< std::is_floating_point< C >::value, bool > isInTheWayOf (const Item &item, const Item &other, const RawShape &scanpoly)
 
template<class C = Coord>
static enable_if_t< std::is_integral< C >::value, bool > isInTheWayOf (const Item &item, const Item &other, const RawShape &scanpoly)
 

Protected Attributes

BinType bin_
 
ItemGroup items_
 
BLConfig< RawShape > config_
 

Private Types

using Base = PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >
 

Private Attributes

bool farea_valid_
 
double farea_
 

Detailed Description

template<class RawShape>
class libnest2d::placers::_BottomLeftPlacer< RawShape >

Member Typedef Documentation

◆ Base

template<class RawShape >
using libnest2d::placers::_BottomLeftPlacer< RawShape >::Base = PlacerBoilerplate<_BottomLeftPlacer<RawShape>, RawShape, _Box<TPoint<RawShape> >, BLConfig<RawShape> >
private

◆ BinType

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::BinType = _Box< TPoint< RawShape > >
inherited

◆ Config

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::Config = BLConfig< RawShape >
inherited

◆ Coord

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::Coord = TCoord<Vertex>
inherited

◆ DefaultIter

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::DefaultIter = typename ItemGroup::const_iterator
inherited

◆ Item

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::Item = _Item<RawShape>
inherited

◆ ItemGroup

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::ItemGroup = _ItemGroup<RawShape>
inherited

◆ Segment

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::Segment = _Segment<Vertex>
inherited

◆ ShapeType

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::ShapeType = RawShape
inherited

◆ Vertex

using libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::Vertex = TPoint<RawShape>
inherited

Member Enumeration Documentation

◆ Dir

template<class RawShape >
enum class libnest2d::placers::_BottomLeftPlacer::Dir
strong

Constructor & Destructor Documentation

◆ _BottomLeftPlacer()

template<class RawShape >
libnest2d::placers::_BottomLeftPlacer< RawShape >::_BottomLeftPlacer ( const BinType bin)
inlineexplicit
43: Base(bin) {}
PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > > Base
Definition bottomleftplacer.hpp:38

Member Function Documentation

◆ _trypack()

template<class RawShape >
PackResult libnest2d::placers::_BottomLeftPlacer< RawShape >::_trypack ( Item item)
inlineprotected
81 {
82
83 // Get initial position for item in the top right corner
85
87 auto eps = config_.epsilon;
88 bool can_move = d > eps;
89 bool can_be_packed = can_move;
90 bool left = true;
91
92 while(can_move) {
93 if(left) { // write previous down move and go down
94 item.translate({0, -d+eps});
95 d = availableSpaceLeft(item);
96 can_move = d > eps;
97 left = false;
98 } else { // write previous left move and go down
99 item.translate({-d+eps, 0});
100 d = availableSpaceDown(item);
101 can_move = d > eps;
102 left = true;
103 }
104 }
105
106 if(can_be_packed) {
107 Item trsh(item.transformedShape());
108 for(auto& v : trsh) can_be_packed = can_be_packed &&
109 getX(v) < bin_.width() &&
110 getY(v) < bin_.height();
111 }
112
113 return can_be_packed? PackResult(item) : PackResult();
114 }
Coord availableSpaceLeft(const Item &item)
Definition bottomleftplacer.hpp:71
void setInitialPosition(Item &item)
Definition bottomleftplacer.hpp:116
Coord availableSpaceDown(const Item &item)
Definition bottomleftplacer.hpp:75
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:539
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:540
TCoord< P > getX(const P &p)
Definition geometry_traits.hpp:424
TCoord< P > getY(const P &p)
Definition geometry_traits.hpp:427

References libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceDown(), libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceLeft(), libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >::bin_, libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >::config_, libnest2d::getX(), libnest2d::getY(), libnest2d::_Box< P >::height(), libnest2d::placers::_BottomLeftPlacer< RawShape >::setInitialPosition(), libnest2d::_Item< RawShape >::transformedShape(), libnest2d::_Item< RawShape >::translate(), and libnest2d::_Box< P >::width().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::trypack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ accept()

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::accept ( PackResult &  r)
inlineinherited
77 {
78 if(r) {
79 r.item_ptr_->translation(r.move_);
80 r.item_ptr_->rotation(r.rot_);
81 items_.emplace_back(*(r.item_ptr_));
82 farea_valid_ = false;
83 }
84 }

◆ availableSpace()

template<class RawShape >
Coord libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpace ( const Item _item,
const Dir  dir 
)
inlineprotected
182 {
183
184 Item item (_item.transformedShape());
185
186
187 std::function<Coord(const Vertex&)> getCoord;
188 std::function< std::pair<Coord, bool>(const Segment&, const Vertex&) >
189 availableDistanceSV;
190
191 std::function< std::pair<Coord, bool>(const Vertex&, const Segment&) >
192 availableDistance;
193
194 if(dir == Dir::LEFT) {
195 getCoord = [](const Vertex& v) { return getX(v); };
196 availableDistance = pointlike::horizontalDistance<Vertex>;
197 availableDistanceSV = [](const Segment& s, const Vertex& v) {
198 auto ret = pointlike::horizontalDistance<Vertex>(v, s);
199 if(ret.second) ret.first = -ret.first;
200 return ret;
201 };
202 }
203 else {
204 getCoord = [](const Vertex& v) { return getY(v); };
205 availableDistance = pointlike::verticalDistance<Vertex>;
206 availableDistanceSV = [](const Segment& s, const Vertex& v) {
207 auto ret = pointlike::verticalDistance<Vertex>(v, s);
208 if(ret.second) ret.first = -ret.first;
209 return ret;
210 };
211 }
212
213 auto&& items_in_the_way = itemsInTheWayOf(item, dir);
214
215 // Comparison function for finding min vertex
216 auto cmp = [&getCoord](const Vertex& v1, const Vertex& v2) {
217 return getCoord(v1) < getCoord(v2);
218 };
219
220 // find minimum left or down coordinate of item
221 auto minvertex_it = std::min_element(item.begin(),
222 item.end(),
223 cmp);
224
225 // Get the initial distance in floating point
226 Coord m = getCoord(*minvertex_it);
227
228 // Check available distance for every vertex of item to the objects
229 // in the way for the nearest intersection
230 if(!items_in_the_way.empty()) { // This is crazy, should be optimized...
231 for(Item& pleft : items_in_the_way) {
232 // For all segments in items_to_left
233
234 assert(pleft.vertexCount() > 0);
235
236 auto trpleft_poly = pleft.transformedShape();
237 auto& trpleft = sl::contour(trpleft_poly);
238 auto first = sl::begin(trpleft);
239 auto next = first + 1;
240 auto endit = sl::end(trpleft);
241
242 while(next != endit) {
243 Segment seg(*(first++), *(next++));
244 for(auto& v : item) { // For all vertices in item
245
246 auto d = availableDistance(v, seg);
247
248 if(d.second && d.first < m) m = d.first;
249 }
250 }
251 }
252
253 auto first = item.begin();
254 auto next = first + 1;
255 auto endit = item.end();
256
257 // For all edges in item:
258 while(next != endit) {
259 Segment seg(*(first++), *(next++));
260
261 // for all shapes in items_to_left
262 for(Item& sh : items_in_the_way) {
263 assert(sh.vertexCount() > 0);
264
265 Item tsh(sh.transformedShape());
266 for(auto& v : tsh) { // For all vertices in item
267
268 auto d = availableDistanceSV(seg, v);
269
270 if(d.second && d.first < m) m = d.first;
271 }
272 }
273 }
274 }
275
276 return m;
277 }
ItemGroup itemsInTheWayOf(const Item &item, const Dir dir)
Definition bottomleftplacer.hpp:161
Slic3r::Polygon & contour(Slic3r::ExPolygon &sh)
Definition geometries.hpp:216
S::iterator begin(S &sh, const PathTag &)
Definition geometry_traits.hpp:614
S::iterator end(S &sh, const PathTag &)
Definition geometry_traits.hpp:620

References libnest2d::_Item< RawShape >::begin(), libnest2d::shapelike::begin(), libnest2d::shapelike::contour(), libnest2d::_Item< RawShape >::end(), libnest2d::shapelike::end(), libnest2d::getX(), libnest2d::getY(), libnest2d::placers::_BottomLeftPlacer< RawShape >::itemsInTheWayOf(), libnest2d::placers::_BottomLeftPlacer< RawShape >::LEFT, and libnest2d::_Item< RawShape >::transformedShape().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceDown(), and libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceLeft().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ availableSpaceDown()

template<class RawShape >
Coord libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceDown ( const Item item)
inline
75 {
76 return availableSpace(item, Dir::DOWN);
77 }
Coord availableSpace(const Item &_item, const Dir dir)
Definition bottomleftplacer.hpp:182

References libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpace(), and libnest2d::placers::_BottomLeftPlacer< RawShape >::DOWN.

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::_trypack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ availableSpaceLeft()

template<class RawShape >
Coord libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpaceLeft ( const Item item)
inline
71 {
72 return availableSpace(item, Dir::LEFT);
73 }

References libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpace(), and libnest2d::placers::_BottomLeftPlacer< RawShape >::LEFT.

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::_trypack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bin() [1/2]

const BinType & libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::bin ( ) const
inlineinherited
52{ return bin_; }

◆ bin() [2/2]

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::bin ( TB &&  b)
inlineinherited
54 {
55 bin_ = std::forward<BinType>(b);
56 }

◆ clearItems()

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::clearItems ( )
inlineinherited
93 {
94 items_.clear();
95 farea_valid_ = false;
96 }

◆ configure()

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::configure ( const Config config)
inlineinherited
58 {
59 config_ = config;
60 }

◆ downPoly()

template<class RawShape >
RawShape libnest2d::placers::_BottomLeftPlacer< RawShape >::downPoly ( const Item item) const
inline
67 {
68 return toWallPoly(item, Dir::DOWN);
69 }
RawShape toWallPoly(const Item &_item, const Dir dir) const
Definition bottomleftplacer.hpp:285

References libnest2d::placers::_BottomLeftPlacer< RawShape >::DOWN, and libnest2d::placers::_BottomLeftPlacer< RawShape >::toWallPoly().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::itemsInTheWayOf().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ filledArea()

double libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::filledArea ( ) const
inlineinherited
98 {
99 if(farea_valid_) return farea_;
100 else {
101 farea_ = .0;
102 std::for_each(items_.begin(), items_.end(),
103 [this] (Item& item) {
104 farea_ += item.area();
105 });
106 farea_valid_ = true;
107 }
108
109 return farea_;
110 }

◆ getItems()

const ItemGroup & libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::getItems ( ) const
inlineinherited
91{ return items_; }

◆ isInTheWayOf() [1/2]

template<class RawShape >
template<class C = Coord>
static enable_if_t< std::is_floating_point< C >::value, bool > libnest2d::placers::_BottomLeftPlacer< RawShape >::isInTheWayOf ( const Item item,
const Item other,
const RawShape &  scanpoly 
)
inlinestaticprotected
133 {
134 auto tsh = other.transformedShape();
135 return ( sl::intersects(tsh, scanpoly) ||
136 sl::isInside(tsh, scanpoly) ) &&
137 ( !sl::intersects(tsh, item.rawShape()) &&
138 !sl::isInside(tsh, item.rawShape()) );
139 }
bool isInside(const TGuest &, const THost &, const PointTag &, const PolygonTag &)
Definition geometry_traits.hpp:672
bool intersects(const S &, const S &)
Definition geometry_traits.hpp:664

References libnest2d::shapelike::intersects(), libnest2d::shapelike::isInside(), libnest2d::_Item< RawShape >::rawShape(), and libnest2d::_Item< RawShape >::transformedShape().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::itemsInTheWayOf().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInTheWayOf() [2/2]

template<class RawShape >
template<class C = Coord>
static enable_if_t< std::is_integral< C >::value, bool > libnest2d::placers::_BottomLeftPlacer< RawShape >::isInTheWayOf ( const Item item,
const Item other,
const RawShape &  scanpoly 
)
inlinestaticprotected
146 {
147 auto tsh = other.transformedShape();
148
149 bool inters_scanpoly = sl::intersects(tsh, scanpoly) &&
150 !sl::touches(tsh, scanpoly);
151 bool inters_item = sl::intersects(tsh, item.rawShape()) &&
152 !sl::touches(tsh, item.rawShape());
153
154 return ( inters_scanpoly ||
155 sl::isInside(tsh, scanpoly)) &&
156 ( !inters_item &&
157 !sl::isInside(tsh, item.rawShape())
158 );
159 }
bool touches(const S &, const S &)
Definition geometry_traits.hpp:688

References libnest2d::shapelike::intersects(), libnest2d::shapelike::isInside(), libnest2d::_Item< RawShape >::rawShape(), libnest2d::shapelike::touches(), and libnest2d::_Item< RawShape >::transformedShape().

+ Here is the call graph for this function:

◆ itemsInTheWayOf()

template<class RawShape >
ItemGroup libnest2d::placers::_BottomLeftPlacer< RawShape >::itemsInTheWayOf ( const Item item,
const Dir  dir 
)
inlineprotected
161 {
162 // Get the left or down polygon, that has the same area as the shadow
163 // of input item reflected to the left or downwards
164 auto&& scanpoly = dir == Dir::LEFT? leftPoly(item) :
165 downPoly(item);
166
167 ItemGroup ret; // packed items 'in the way' of item
168 ret.reserve(items_.size());
169
170 // Predicate to find items that are 'in the way' for left (down) move
171 auto predicate = [&scanpoly, &item](const Item& it) {
172 return isInTheWayOf(item, it, scanpoly);
173 };
174
175 // Get the items that are in the way for the left (or down) movement
176 std::copy_if(items_.begin(), items_.end(),
177 std::back_inserter(ret), predicate);
178
179 return ret;
180 }
RawShape leftPoly(const Item &item) const
Definition bottomleftplacer.hpp:63
RawShape downPoly(const Item &item) const
Definition bottomleftplacer.hpp:67
static enable_if_t< std::is_floating_point< C >::value, bool > isInTheWayOf(const Item &item, const Item &other, const RawShape &scanpoly)
Definition bottomleftplacer.hpp:130

References libnest2d::placers::_BottomLeftPlacer< RawShape >::downPoly(), libnest2d::placers::_BottomLeftPlacer< RawShape >::isInTheWayOf(), libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >::items_, libnest2d::placers::_BottomLeftPlacer< RawShape >::LEFT, and libnest2d::placers::_BottomLeftPlacer< RawShape >::leftPoly().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::availableSpace().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ leftPoly()

template<class RawShape >
RawShape libnest2d::placers::_BottomLeftPlacer< RawShape >::leftPoly ( const Item item) const
inline
63 {
64 return toWallPoly(item, Dir::LEFT);
65 }

References libnest2d::placers::_BottomLeftPlacer< RawShape >::LEFT, and libnest2d::placers::_BottomLeftPlacer< RawShape >::toWallPoly().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::itemsInTheWayOf().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pack()

bool libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::pack ( Item item,
const Range &  rem = Range() 
)
inlineinherited
63 {
64 auto&& r = static_cast<Subclass*>(this)->trypack(item, rem);
65 if(r) {
66 items_.emplace_back(*(r.item_ptr_));
67 farea_valid_ = false;
68 }
69 return r;
70 }

◆ preload()

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::preload ( const ItemGroup packeditems)
inlineinherited
72 {
73 items_.insert(items_.end(), packeditems.begin(), packeditems.end());
74 farea_valid_ = false;
75 }

◆ setInitialPosition()

template<class RawShape >
void libnest2d::placers::_BottomLeftPlacer< RawShape >::setInitialPosition ( Item item)
inlineprotected
116 {
117 auto bb = item.boundingBox();
118
119 Vertex v = { getX(bb.maxCorner()), getY(bb.minCorner()) };
120
121
122 Coord dx = getX(bin_.maxCorner()) - getX(v);
123 Coord dy = getY(bin_.maxCorner()) - getY(v);
124
125 item.translate({dx, dy});
126 }
const P & maxCorner() const BP2D_NOEXCEPT
Definition geometry_traits.hpp:191

References libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >::bin_, libnest2d::_Item< RawShape >::boundingBox(), libnest2d::getX(), libnest2d::getY(), libnest2d::_Box< P >::maxCorner(), and libnest2d::_Item< RawShape >::translate().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::_trypack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toWallPoly()

template<class RawShape >
RawShape libnest2d::placers::_BottomLeftPlacer< RawShape >::toWallPoly ( const Item _item,
const Dir  dir 
) const
inlineprotected

Implementation of the left (and down) polygon as described by [López-Camacho et al. 2013]\ (http://www.cs.stir.ac.uk/~goc/papers/EffectiveHueristic2DAOR2013.pdf) see algorithm 8 for details...

285 {
286 // The variable names reflect the case of left polygon calculation.
287 //
288 // We will iterate through the item's vertices and search for the top
289 // and bottom vertices (or right and left if dir==Dir::DOWN).
290 // Save the relevant vertices and their indices into `bottom` and
291 // `top` vectors. In case of left polygon construction these will
292 // contain the top and bottom polygons which have the same vertical
293 // coordinates (in case there is more of them).
294 //
295 // We get the leftmost (or downmost) vertex from the `bottom` and `top`
296 // vectors and construct the final polygon.
297
298 Item item (_item.transformedShape());
299
300 auto getCoord = [dir](const Vertex& v) {
301 return dir == Dir::LEFT? getY(v) : getX(v);
302 };
303
304 Coord max_y = std::numeric_limits<Coord>::min();
305 Coord min_y = std::numeric_limits<Coord>::max();
306
307 using El = std::pair<size_t, std::reference_wrapper<const Vertex>>;
308
309 std::function<bool(const El&, const El&)> cmp;
310
311 if(dir == Dir::LEFT)
312 cmp = [](const El& e1, const El& e2) {
313 return getX(e1.second.get()) < getX(e2.second.get());
314 };
315 else
316 cmp = [](const El& e1, const El& e2) {
317 return getY(e1.second.get()) < getY(e2.second.get());
318 };
319
320 std::vector< El > top;
321 std::vector< El > bottom;
322
323 size_t idx = 0;
324 for(auto& v : item) { // Find the bottom and top vertices and save them
325 auto vref = std::cref(v);
326 auto vy = getCoord(v);
327
328 if( vy > max_y ) {
329 max_y = vy;
330 top.clear();
331 top.emplace_back(idx, vref);
332 }
333 else if(vy == max_y) { top.emplace_back(idx, vref); }
334
335 if(vy < min_y) {
336 min_y = vy;
337 bottom.clear();
338 bottom.emplace_back(idx, vref);
339 }
340 else if(vy == min_y) { bottom.emplace_back(idx, vref); }
341
342 idx++;
343 }
344
345 // Get the top and bottom leftmost vertices, or the right and left
346 // downmost vertices (if dir == Dir::DOWN)
347 auto topleft_it = std::min_element(top.begin(), top.end(), cmp);
348 auto bottomleft_it =
349 std::min_element(bottom.begin(), bottom.end(), cmp);
350
351 auto& topleft_vertex = topleft_it->second.get();
352 auto& bottomleft_vertex = bottomleft_it->second.get();
353
354 // Start and finish positions for the vertices that will be part of the
355 // new polygon
356 auto start = std::min(topleft_it->first, bottomleft_it->first);
357 auto finish = std::max(topleft_it->first, bottomleft_it->first);
358
359 RawShape ret;
360
361 // the return shape
362 auto& rsh = sl::contour(ret);
363
364 // reserve for all vertices plus 2 for the left horizontal wall, 2 for
365 // the additional vertices for maintaning min object distance
366 sl::reserve(rsh, finish-start+4);
367
368 auto addOthers_ = [&rsh, finish, start, &item](){
369 for(size_t i = start+1; i < finish; i++)
370 sl::addVertex(rsh, item.vertex(i));
371 };
372
373 auto reverseAddOthers_ = [&rsh, finish, start, &item](){
374 for(auto i = finish-1; i > start; i--)
375 sl::addVertex(rsh, item.vertex(static_cast<unsigned long>(i)));
376 };
377
378 auto addOthers = [&]() {
379 if constexpr (!is_clockwise<RawShape>())
380 addOthers_();
381 else
382 reverseAddOthers_();
383 };
384
385 // Final polygon construction...
386
387 // Clockwise polygon construction
388
389 sl::addVertex(rsh, topleft_vertex);
390
391 if(dir == Dir::LEFT) addOthers();
392 else {
393 sl::addVertex(rsh, {getX(topleft_vertex), 0});
394 sl::addVertex(rsh, {getX(bottomleft_vertex), 0});
395 }
396
397 sl::addVertex(rsh, bottomleft_vertex);
398
399 if(dir == Dir::LEFT) {
400 sl::addVertex(rsh, {0, getY(bottomleft_vertex)});
401 sl::addVertex(rsh, {0, getY(topleft_vertex)});
402 }
403 else addOthers();
404
405
406 // Close the polygon
407 if constexpr (ClosureTypeV<RawShape> == Closure::CLOSED)
408 sl::addVertex(rsh, topleft_vertex);
409
410 if constexpr (!is_clockwise<RawShape>())
411 std::reverse(rsh.begin(), rsh.end());
412
413 return ret;
414 }
void addVertex(Slic3r::Polygon &sh, const PathTag &, const Slic3r::Point &p)
Definition geometries.hpp:234
void reserve(Slic3r::Polygon &p, size_t vertex_capacity, const PathTag &)
Definition geometries.hpp:228

References libnest2d::shapelike::addVertex(), libnest2d::CLOSED, libnest2d::shapelike::contour(), libnest2d::getX(), libnest2d::getY(), libnest2d::placers::_BottomLeftPlacer< RawShape >::LEFT, libnest2d::shapelike::reserve(), libnest2d::_Item< RawShape >::transformedShape(), and libnest2d::_Item< RawShape >::vertex().

Referenced by libnest2d::placers::_BottomLeftPlacer< RawShape >::downPoly(), and libnest2d::placers::_BottomLeftPlacer< RawShape >::leftPoly().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trypack()

template<class RawShape >
template<class Range = ConstItemRange<typename Base::DefaultIter>>
PackResult libnest2d::placers::_BottomLeftPlacer< RawShape >::trypack ( Item item,
const Range &  = Range() 
)
inline
48 {
49 auto r = _trypack(item);
50 if(!r && Base::config_.allow_rotations) {
51
52 item.rotate(Degrees(90));
53 r =_trypack(item);
54 }
55 return r;
56 }
PackResult _trypack(Item &item)
Definition bottomleftplacer.hpp:81

References libnest2d::placers::_BottomLeftPlacer< RawShape >::_trypack(), libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape >, RawShape, _Box< TPoint< RawShape > >, BLConfig< RawShape > >::config_, and libnest2d::_Item< RawShape >::rotate().

+ Here is the call graph for this function:

◆ unpackLast()

void libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::unpackLast ( )
inlineinherited
86 {
87 items_.pop_back();
88 farea_valid_ = false;
89 }

Member Data Documentation

◆ bin_

BinType libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::bin_
protectedinherited

◆ config_

BLConfig< RawShape > libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::config_
protectedinherited

◆ farea_

double libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::farea_
mutableprivateinherited

◆ farea_valid_

bool libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::farea_valid_
mutableprivateinherited

◆ items_

ItemGroup libnest2d::placers::PlacerBoilerplate< _BottomLeftPlacer< RawShape > , RawShape, _Box< TPoint< RawShape > > , BLConfig< RawShape > >::items_
protectedinherited

The documentation for this class was generated from the following file: