1 #ifndef LIBNEST2D_HPP
2 #define LIBNEST2D_HPP
3 
4 // The type of backend should be set conditionally by the cmake configuriation
5 // for now we set it statically to clipper backend
6 #ifdef LIBNEST2D_GEOMETRIES_clipper
7 #include <libnest2d/backends/clipper/geometries.hpp>
8 #endif
9 
10 #ifdef LIBNEST2D_OPTIMIZER_nlopt
11 // We include the stock optimizers for local and global optimization
12 #include <libnest2d/optimizers/nlopt/subplex.hpp>     // Local subplex for NfpPlacer
13 #include <libnest2d/optimizers/nlopt/genetic.hpp>     // Genetic for min. bounding box
14 #endif
15 
16 #include <libnest2d/nester.hpp>
17 #include <libnest2d/placers/bottomleftplacer.hpp>
18 #include <libnest2d/placers/nfpplacer.hpp>
19 #include <libnest2d/selections/firstfit.hpp>
20 #include <libnest2d/selections/filler.hpp>
21 #include <libnest2d/selections/djd_heuristic.hpp>
22 
23 namespace libnest2d {
24 
25 using Point = PointImpl;
26 using Coord = TCoord<PointImpl>;
27 using Box = _Box<PointImpl>;
28 using Segment = _Segment<PointImpl>;
29 using Circle = _Circle<PointImpl>;
30 
31 using Item = _Item<PolygonImpl>;
32 using Rectangle = _Rectangle<PolygonImpl>;
33 using PackGroup = _PackGroup<PolygonImpl>;
34 
35 using FillerSelection = selections::_FillerSelection<PolygonImpl>;
36 using FirstFitSelection = selections::_FirstFitSelection<PolygonImpl>;
37 using DJDHeuristic  = selections::_DJDHeuristic<PolygonImpl>;
38 
39 template<class Bin> // Generic placer for arbitrary bin types
40 using _NfpPlacer = placers::_NofitPolyPlacer<PolygonImpl, Bin>;
41 
42 // NfpPlacer is with Box bin
43 using NfpPlacer = _NfpPlacer<Box>;
44 
45 // This supports only box shaped bins
46 using BottomLeftPlacer = placers::_BottomLeftPlacer<PolygonImpl>;
47 
48 #ifdef LIBNEST2D_STATIC
49 
50 extern template class _Nester<NfpPlacer, FirstFitSelection>;
51 extern template class _Nester<BottomLeftPlacer, FirstFitSelection>;
52 extern template std::size_t _Nester<NfpPlacer, FirstFitSelection>::execute(
53         std::vector<Item>::iterator, std::vector<Item>::iterator);
54 extern template std::size_t _Nester<BottomLeftPlacer, FirstFitSelection>::execute(
55         std::vector<Item>::iterator, std::vector<Item>::iterator);
56 
57 #endif
58 
59 template<class Placer = NfpPlacer, class Selector = FirstFitSelection>
60 struct NestConfig {
61     typename Placer::Config placer_config;
62     typename Selector::Config selector_config;
63     using Placement = typename Placer::Config;
64     using Selection = typename Selector::Config;
65 
66     NestConfig() = default;
NestConfiglibnest2d::NestConfig67     NestConfig(const typename Placer::Config &cfg)   : placer_config{cfg} {}
NestConfiglibnest2d::NestConfig68     NestConfig(const typename Selector::Config &cfg) : selector_config{cfg} {}
NestConfiglibnest2d::NestConfig69     NestConfig(const typename Placer::Config &  pcfg,
70                const typename Selector::Config &scfg)
71         : placer_config{pcfg}, selector_config{scfg} {}
72 };
73 
74 struct NestControl {
75     ProgressFunction progressfn;
__anonf35bbbd10102libnest2d::NestControl76     StopCondition stopcond = []{ return false; };
77 
78     NestControl() = default;
NestControllibnest2d::NestControl79     NestControl(ProgressFunction pr) : progressfn{std::move(pr)} {}
NestControllibnest2d::NestControl80     NestControl(StopCondition sc) : stopcond{std::move(sc)} {}
NestControllibnest2d::NestControl81     NestControl(ProgressFunction pr, StopCondition sc)
82         : progressfn{std::move(pr)}, stopcond{std::move(sc)}
83     {}
84 };
85 
86 template<class Placer = NfpPlacer,
87          class Selector = FirstFitSelection,
88          class Iterator = std::vector<Item>::iterator>
nest(Iterator from,Iterator to,const typename Placer::BinType & bin,Coord dist=0,const NestConfig<Placer,Selector> & cfg={},NestControl ctl={})89 std::size_t nest(Iterator from, Iterator to,
90                  const typename Placer::BinType & bin,
91                  Coord dist = 0,
92                  const NestConfig<Placer, Selector> &cfg = {},
93                  NestControl ctl = {})
94 {
95     _Nester<Placer, Selector> nester{bin, dist, cfg.placer_config, cfg.selector_config};
96     if(ctl.progressfn) nester.progressIndicator(ctl.progressfn);
97     if(ctl.stopcond) nester.stopCondition(ctl.stopcond);
98     return nester.execute(from, to);
99 }
100 
101 #ifdef LIBNEST2D_STATIC
102 
103 extern template class _Nester<NfpPlacer, FirstFitSelection>;
104 extern template class _Nester<BottomLeftPlacer, FirstFitSelection>;
105 extern template std::size_t nest(std::vector<Item>::iterator from,
106                                  std::vector<Item>::iterator to,
107                                  const Box & bin,
108                                  Coord dist,
109                                  const NestConfig<NfpPlacer, FirstFitSelection> &cfg,
110                                  NestControl ctl);
111 extern template std::size_t nest(std::vector<Item>::iterator from,
112                                  std::vector<Item>::iterator to,
113                                  const Box & bin,
114                                  Coord dist,
115                                  const NestConfig<BottomLeftPlacer, FirstFitSelection> &cfg,
116                                  NestControl ctl);
117 
118 #endif
119 
120 template<class Placer = NfpPlacer,
121          class Selector = FirstFitSelection,
122          class Container = std::vector<Item>>
nest(Container && cont,const typename Placer::BinType & bin,Coord dist=0,const NestConfig<Placer,Selector> & cfg={},NestControl ctl={})123 std::size_t nest(Container&& cont,
124                  const typename Placer::BinType & bin,
125                  Coord dist = 0,
126                  const NestConfig<Placer, Selector> &cfg = {},
127                  NestControl ctl = {})
128 {
129     return nest<Placer, Selector>(cont.begin(), cont.end(), bin, dist, cfg, ctl);
130 }
131 
mm(T val=T (1))132 template<class T = double> enable_if_t<std::is_arithmetic<T>::value, TCoord<PointImpl>> mm(T val = T(1))
133 {
134     return TCoord<PointImpl>(val * CoordType<PointImpl>::MM_IN_COORDS);
135 }
136 
137 }
138 
139 #endif // LIBNEST2D_HPP
140