Back-porting improvements for libnest2d
This commit is contained in:
parent
ab3890dab5
commit
f117d02750
@ -28,4 +28,4 @@ add_library(libnest2d STATIC ${LIBNEST2D_SRCFILES})
|
||||
|
||||
target_include_directories(libnest2d PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
target_link_libraries(libnest2d PUBLIC clipper NLopt::nlopt TBB::tbb Boost::boost)
|
||||
target_compile_definitions(libnest2d PUBLIC USE_TBB LIBNEST2D_STATIC LIBNEST2D_OPTIMIZER_nlopt LIBNEST2D_GEOMETRIES_clipper)
|
||||
target_compile_definitions(libnest2d PUBLIC LIBNEST2D_THREADING_tbb LIBNEST2D_STATIC LIBNEST2D_OPTIMIZER_nlopt LIBNEST2D_GEOMETRIES_clipper)
|
||||
|
@ -26,7 +26,10 @@ template<> struct ShapeTag<PointImpl> { using Type = PointTag; };
|
||||
|
||||
// Type of coordinate units used by Clipper. Enough to specialize for point,
|
||||
// the rest of the types will work (Path, Polygon)
|
||||
template<> struct CoordType<PointImpl> { using Type = ClipperLib::cInt; };
|
||||
template<> struct CoordType<PointImpl> {
|
||||
using Type = ClipperLib::cInt;
|
||||
static const constexpr ClipperLib::cInt MM_IN_COORDS = 1000000;
|
||||
};
|
||||
|
||||
// Enough to specialize for path, it will work for multishape and Polygon
|
||||
template<> struct PointType<PathImpl> { using Type = PointImpl; };
|
||||
@ -95,6 +98,9 @@ inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance, const PolygonTag
|
||||
// Offsetting reverts the orientation and also removes the last vertex
|
||||
// so boost will not have a closed polygon.
|
||||
|
||||
// we plan to replace contours
|
||||
sh.Holes.clear();
|
||||
|
||||
bool found_the_contour = false;
|
||||
for(auto& r : result) {
|
||||
if(ClipperLib::Orientation(r)) {
|
||||
|
@ -47,7 +47,8 @@ using TPoint = typename PointType<remove_cvref_t<Shape>>::Type;
|
||||
|
||||
/// Getting the coordinate data type for a geometry class.
|
||||
template<class GeomClass> struct CoordType {
|
||||
using Type = typename CoordType<TPoint<GeomClass>>::Type;
|
||||
using Type = typename CoordType<TPoint<GeomClass>>::Type;
|
||||
static const constexpr Type MM_IN_COORDS = Type{1};
|
||||
};
|
||||
|
||||
/// TCoord<GeomType> as shorthand for typename `CoordType<GeomType>::Type`.
|
||||
|
@ -130,6 +130,11 @@ std::size_t nest(Container&& cont,
|
||||
return nest<Placer, Selector>(cont.begin(), cont.end(), bin, dist, cfg, ctl);
|
||||
}
|
||||
|
||||
template<class T = double> enable_if_t<std::is_arithmetic<T>::value, TCoord<PointImpl>> mm(T val = T(1))
|
||||
{
|
||||
return TCoord<PointImpl>(val * CoordType<PointImpl>::MM_IN_COORDS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBNEST2D_HPP
|
||||
|
63
src/libnest2d/include/libnest2d/parallel.hpp
Normal file
63
src/libnest2d/include/libnest2d/parallel.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#ifndef LIBNEST2D_PARALLEL_HPP
|
||||
#define LIBNEST2D_PARALLEL_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
#ifdef LIBNEST2D_THREADING_tbb
|
||||
#include <tbb/parallel_for.h>
|
||||
#endif
|
||||
|
||||
#ifdef LIBNEST2D_THREADING_omp
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
namespace libnest2d { namespace __parallel {
|
||||
|
||||
template<class It>
|
||||
using TIteratorValue = typename std::iterator_traits<It>::value_type;
|
||||
|
||||
template<class Iterator>
|
||||
inline void enumerate(
|
||||
Iterator from, Iterator to,
|
||||
std::function<void(TIteratorValue<Iterator>, size_t)> fn,
|
||||
std::launch policy = std::launch::deferred | std::launch::async)
|
||||
{
|
||||
using TN = size_t;
|
||||
auto iN = to-from;
|
||||
TN N = iN < 0? 0 : TN(iN);
|
||||
|
||||
#ifdef LIBNEST2D_THREADING_tbb
|
||||
if((policy & std::launch::async) == std::launch::async) {
|
||||
tbb::parallel_for<TN>(0, N, [from, fn] (TN n) { fn(*(from + n), n); } );
|
||||
} else {
|
||||
for(TN n = 0; n < N; n++) fn(*(from + n), n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIBNEST2D_THREADING_omp
|
||||
if((policy & std::launch::async) == std::launch::async) {
|
||||
#pragma omp parallel for
|
||||
for(int n = 0; n < int(N); n++) fn(*(from + n), TN(n));
|
||||
}
|
||||
else {
|
||||
for(TN n = 0; n < N; n++) fn(*(from + n), n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIBNEST2D_THREADING_std
|
||||
std::vector<std::future<void>> rets(N);
|
||||
|
||||
auto it = from;
|
||||
for(TN b = 0; b < N; b++) {
|
||||
rets[b] = std::async(policy, fn, *it++, unsigned(b));
|
||||
}
|
||||
|
||||
for(TN fi = 0; fi < N; ++fi) rets[fi].wait();
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif //LIBNEST2D_PARALLEL_HPP
|
@ -20,59 +20,9 @@
|
||||
// temporary
|
||||
//#include "../tools/svgtools.hpp"
|
||||
|
||||
#ifdef USE_TBB
|
||||
#include <tbb/parallel_for.h>
|
||||
#elif defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
#include <libnest2d/parallel.hpp>
|
||||
|
||||
namespace libnest2d {
|
||||
|
||||
namespace __parallel {
|
||||
|
||||
using std::function;
|
||||
using std::iterator_traits;
|
||||
template<class It>
|
||||
using TIteratorValue = typename iterator_traits<It>::value_type;
|
||||
|
||||
template<class Iterator>
|
||||
inline void enumerate(
|
||||
Iterator from, Iterator to,
|
||||
function<void(TIteratorValue<Iterator>, size_t)> fn,
|
||||
std::launch policy = std::launch::deferred | std::launch::async)
|
||||
{
|
||||
using TN = size_t;
|
||||
auto iN = to-from;
|
||||
TN N = iN < 0? 0 : TN(iN);
|
||||
|
||||
#ifdef USE_TBB
|
||||
if((policy & std::launch::async) == std::launch::async) {
|
||||
tbb::parallel_for<TN>(0, N, [from, fn] (TN n) { fn(*(from + n), n); } );
|
||||
} else {
|
||||
for(TN n = 0; n < N; n++) fn(*(from + n), n);
|
||||
}
|
||||
#elif defined(_OPENMP)
|
||||
if((policy & std::launch::async) == std::launch::async) {
|
||||
#pragma omp parallel for
|
||||
for(int n = 0; n < int(N); n++) fn(*(from + n), TN(n));
|
||||
}
|
||||
else {
|
||||
for(TN n = 0; n < N; n++) fn(*(from + n), n);
|
||||
}
|
||||
#else
|
||||
std::vector<std::future<void>> rets(N);
|
||||
|
||||
auto it = from;
|
||||
for(TN b = 0; b < N; b++) {
|
||||
rets[b] = std::async(policy, fn, *it++, unsigned(b));
|
||||
}
|
||||
|
||||
for(TN fi = 0; fi < N; ++fi) rets[fi].wait();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace placers {
|
||||
|
||||
template<class RawShape>
|
||||
|
@ -54,10 +54,10 @@ public:
|
||||
if(conf_.origo_location == BOTTOMLEFT) {
|
||||
auto d = static_cast<Coord>(
|
||||
std::round(conf_.height*conf_.mm_in_coord_units) );
|
||||
|
||||
|
||||
auto& contour = shapelike::contour(tsh);
|
||||
for(auto& v : contour) setY(v, -getY(v) + d);
|
||||
|
||||
|
||||
auto& holes = shapelike::holes(tsh);
|
||||
for(auto& h : holes) for(auto& v : h) setY(v, -getY(v) + d);
|
||||
|
||||
@ -81,6 +81,18 @@ public:
|
||||
finishLayer();
|
||||
}
|
||||
}
|
||||
|
||||
template<class ItemIt> void writeItems(ItemIt from, ItemIt to) {
|
||||
auto it = from;
|
||||
PackGroup pg;
|
||||
while(it != to) {
|
||||
if(it->binId() == BIN_ID_UNSET) continue;
|
||||
while(pg.size() <= size_t(it->binId())) pg.emplace_back();
|
||||
pg[it->binId()].emplace_back(*it);
|
||||
++it;
|
||||
}
|
||||
writePackGroup(pg);
|
||||
}
|
||||
|
||||
void addLayer() {
|
||||
svg_layers_.emplace_back(header());
|
||||
|
@ -2,10 +2,10 @@
|
||||
#define PRINTER_PARTS_H
|
||||
|
||||
#include <vector>
|
||||
#include <libnest2d/backends/clipper/clipper_polygon.hpp>
|
||||
#include <libnest2d/libnest2d.hpp>
|
||||
|
||||
using TestData = std::vector<ClipperLib::Path>;
|
||||
using TestDataEx = std::vector<ClipperLib::Polygon>;
|
||||
using TestData = std::vector<libnest2d::PathImpl>;
|
||||
using TestDataEx = std::vector<libnest2d::PolygonImpl>;
|
||||
|
||||
extern const TestData PRINTER_PART_POLYGONS;
|
||||
extern const TestData STEGOSAUR_POLYGONS;
|
||||
|
Loading…
Reference in New Issue
Block a user