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