Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortamasmeszaros <meszaros.q@gmail.com>2019-07-12 22:03:49 +0300
committertamasmeszaros <meszaros.q@gmail.com>2019-07-12 22:17:11 +0300
commitdf7bb94dafea6a64922184fe65db3c61f7c85da0 (patch)
tree9338cc78208b7f8b9c32dd4a2d5842ef881f2599 /src/libnest2d
parent9372f1c6ad15d6d4f938f167625ff9e8e5905cb1 (diff)
Not handling logical beds in arrange()
Diffstat (limited to 'src/libnest2d')
-rw-r--r--src/libnest2d/include/libnest2d.h23
-rw-r--r--src/libnest2d/include/libnest2d/libnest2d.hpp141
-rw-r--r--src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp7
-rw-r--r--src/libnest2d/include/libnest2d/selections/firstfit.hpp6
-rw-r--r--src/libnest2d/tests/test.cpp97
5 files changed, 122 insertions, 152 deletions
diff --git a/src/libnest2d/include/libnest2d.h b/src/libnest2d/include/libnest2d.h
index f1d2506f4..5f7a29dfb 100644
--- a/src/libnest2d/include/libnest2d.h
+++ b/src/libnest2d/include/libnest2d.h
@@ -59,20 +59,20 @@ extern template PackGroup Nester<BottomLeftPlacer, FirstFitSelection>::execute(
template<class Placer = NfpPlacer,
class Selector = FirstFitSelection,
class Iterator = std::vector<Item>::iterator>
-PackGroup nest(Iterator from, Iterator to,
+void nest(Iterator from, Iterator to,
const typename Placer::BinType& bin,
Coord dist = 0,
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {})
{
Nester<Placer, Selector> nester(bin, dist, pconf, sconf);
- return nester.execute(from, to);
+ nester.execute(from, to);
}
template<class Placer = NfpPlacer,
class Selector = FirstFitSelection,
class Iterator = std::vector<Item>::iterator>
-PackGroup nest(Iterator from, Iterator to,
+void nest(Iterator from, Iterator to,
const typename Placer::BinType& bin,
ProgressFunction prg,
StopCondition scond = []() { return false; },
@@ -83,7 +83,7 @@ PackGroup nest(Iterator from, Iterator to,
Nester<Placer, Selector> nester(bin, dist, pconf, sconf);
if(prg) nester.progressIndicator(prg);
if(scond) nester.stopCondition(scond);
- return nester.execute(from, to);
+ nester.execute(from, to);
}
#ifdef LIBNEST2D_STATIC
@@ -91,14 +91,14 @@ PackGroup nest(Iterator from, Iterator to,
extern template class Nester<NfpPlacer, FirstFitSelection>;
extern template class Nester<BottomLeftPlacer, FirstFitSelection>;
-extern template PackGroup nest(std::vector<Item>::iterator from,
+extern template void nest(std::vector<Item>::iterator from,
std::vector<Item>::iterator to,
const Box& bin,
Coord dist = 0,
const NfpPlacer::Config& pconf,
const FirstFitSelection::Config& sconf);
-extern template PackGroup nest(std::vector<Item>::iterator from,
+extern template void nest(std::vector<Item>::iterator from,
std::vector<Item>::iterator to,
const Box& bin,
ProgressFunction prg,
@@ -112,20 +112,19 @@ extern template PackGroup nest(std::vector<Item>::iterator from,
template<class Placer = NfpPlacer,
class Selector = FirstFitSelection,
class Container = std::vector<Item>>
-PackGroup nest(Container&& cont,
+void nest(Container&& cont,
const typename Placer::BinType& bin,
Coord dist = 0,
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {})
{
- return nest<Placer, Selector>(cont.begin(), cont.end(),
- bin, dist, pconf, sconf);
+ nest<Placer, Selector>(cont.begin(), cont.end(), bin, dist, pconf, sconf);
}
template<class Placer = NfpPlacer,
class Selector = FirstFitSelection,
class Container = std::vector<Item>>
-PackGroup nest(Container&& cont,
+void nest(Container&& cont,
const typename Placer::BinType& bin,
ProgressFunction prg,
StopCondition scond = []() { return false; },
@@ -133,8 +132,8 @@ PackGroup nest(Container&& cont,
const typename Placer::Config& pconf = {},
const typename Selector::Config& sconf = {})
{
- return nest<Placer, Selector>(cont.begin(), cont.end(),
- bin, prg, scond, dist, pconf, sconf);
+ nest<Placer, Selector>(cont.begin(), cont.end(), bin, prg, scond, dist,
+ pconf, sconf);
}
}
diff --git a/src/libnest2d/include/libnest2d/libnest2d.hpp b/src/libnest2d/include/libnest2d/libnest2d.hpp
index 99c8c90c1..a83a16ecf 100644
--- a/src/libnest2d/include/libnest2d/libnest2d.hpp
+++ b/src/libnest2d/include/libnest2d/libnest2d.hpp
@@ -12,6 +12,8 @@
namespace libnest2d {
+static const constexpr int BIN_ID_UNSET = -1;
+
/**
* \brief An item to be placed on a bin.
*
@@ -34,9 +36,9 @@ class _Item {
RawShape sh_;
// Transformation data
- Vertex translation_;
- Radians rotation_;
- Coord inflation_;
+ Vertex translation_{0, 0};
+ Radians rotation_{0.0};
+ Coord inflation_{0};
// Info about whether the transformations will have to take place
// This is needed because if floating point is used, it is hard to say
@@ -66,9 +68,7 @@ class _Item {
BBCache(): valid(false) {}
} bb_cache_;
- static const size_t ID_UNSET = size_t(-1);
-
- size_t id_{ID_UNSET};
+ int binid_{BIN_ID_UNSET};
bool fixed_{false};
public:
@@ -149,8 +149,8 @@ public:
inline bool isFixed() const noexcept { return fixed_; }
inline void markAsFixed(bool fixed = true) { fixed_ = fixed; }
- inline void id(size_t idx) { id_ = idx; }
- inline long id() const noexcept { return id_; }
+ inline void binId(int idx) { binid_ = idx; }
+ inline int binId() const noexcept { return binid_; }
/**
* @brief Convert the polygon to string representation. The format depends
@@ -766,25 +766,6 @@ public:
void clear() { impl_.clear(); }
};
-using BinIdx = unsigned;
-template<class S, class Key = size_t> using _NestResult =
- std::vector<
- std::tuple<Key, // Identifier of the original shape
- TPoint<S>, // Translation calculated by nesting
- Radians, // Rotation calculated by nesting
- BinIdx> // Logical bin index, first is zero
- >;
-
-template<class T> struct Indexed {
- using ShapeType = T;
- static T& get(T& obj) { return obj; }
-};
-
-template<class K, class S> struct Indexed<std::pair<K, S>> {
- using ShapeType = S;
- static S& get(std::pair<K, S>& obj) { return obj.second; }
-};
-
/**
* The Arranger is the front-end class for the libnest2d library. It takes the
* input items and outputs the items with the proper transformations to be
@@ -805,7 +786,6 @@ public:
using Coord = TCoord<TPoint<typename Item::ShapeType>>;
using PackGroup = _PackGroup<typename Item::ShapeType>;
using ResultType = PackGroup;
- template<class K> using NestResult = _NestResult<ShapeType, K>;
private:
BinType bin_;
@@ -816,8 +796,13 @@ private:
using TPItem = remove_cvref_t<Item>;
using TSItem = remove_cvref_t<SItem>;
- std::vector<TPItem> item_cache_;
StopCondition stopfn_;
+
+ template<class It> using TVal = remove_cvref_t<typename It::value_type>;
+
+ template<class It, class Out>
+ using ConvertibleOnly =
+ enable_if_t< std::is_convertible<TVal<It>, TPItem>::value, void>;
public:
@@ -864,12 +849,20 @@ public:
* The number of groups in the pack group is the number of bins opened by
* the selection algorithm.
*/
- template<class It, class Key = size_t>
- inline const NestResult<Key> execute(It from, It to,
- std::function<Key(It)> keyfn = nullptr)
+ template<class It>
+ inline ConvertibleOnly<It, void> execute(It from, It to)
{
- if (!keyfn) keyfn = [to](It it) { return to - it; };
- return _execute(from, to, keyfn);
+ auto infl = static_cast<Coord>(std::ceil(min_obj_distance_/2.0));
+ if(infl > 0) std::for_each(from, to, [this, infl](Item& item) {
+ item.inflate(infl);
+ });
+
+ selector_.template packItems<PlacementStrategy>(
+ from, to, bin_, pconfig_);
+
+ if(min_obj_distance_ > 0) std::for_each(from, to, [infl](Item& item) {
+ item.inflate(-infl);
+ });
}
/// Set a progress indicator function object for the selector.
@@ -890,74 +883,32 @@ public:
}
private:
-
- template<class It> using TVal = remove_cvref_t<typename It::value_type>;
-
- template<class It, class Out>
- using ConvertibleOnly =
- enable_if_t< std::is_convertible<TVal<It>, TPItem>::value, void>;
-
- template<class It, class Out>
- using NotConvertibleOnly =
- enable_if_t< ! std::is_convertible<TVal<It>, TPItem>::value, void>;
-
+
+
// This function will be used only if the iterators are pointing to
// a type compatible with the libnets2d::_Item template.
// This way we can use references to input elements as they will
// have to exist for the lifetime of this call.
- template<class It, class Key>
- inline ConvertibleOnly<It, const NestResult<Key>> _execute(
- It from, It to, std::function<Key(It)> keyfn)
- {
- {
- auto it = from; size_t id = 0;
- while(it != to)
- if (it->id() == Item::ID_UNSET) (it++)->id(id++);
- else { id = it->id() + 1; ++it; }
- }
-
- NestResult<Key> result(to - from);
-
- __execute(from, to, keyfn);
-
- BinIdx binidx = 0;
- for(auto &itmgrp : lastResult()) {
- for(const Item& itm : itmgrp)
- result[itm.id()] =
- std::make_tuple(keyfn(from + itm.id()), itm.translation(),
- itm.rotation(), binidx);
-
- ++binidx;
- }
-
- return result;
- }
+// template<class It, class Key>
+// inline ConvertibleOnly<It, void> _execute(It from, It to)
+// {
+// __execute(from, to);
+// }
- template<class It, class Key = size_t>
- inline NotConvertibleOnly<It, const NestResult<Key>> _execute(
- It from, It to, std::function<Key(It)> keyfn)
- {
- item_cache_.reserve(to - from);
- for(auto it = from; it != to; ++it)
- item_cache_.emplace_back(Indexed<typename It::value_type>::get(*it));
-
- return _execute(item_cache_.begin(), item_cache_.end(), keyfn);
- }
-
- template<class It> inline void __execute(It from, It to)
- {
- auto infl = static_cast<Coord>(std::ceil(min_obj_distance_/2.0));
- if(infl > 0) std::for_each(from, to, [this](Item& item) {
- item.inflate(infl);
- });
+// template<class It> inline void _execute(It from, It to)
+// {
+// auto infl = static_cast<Coord>(std::ceil(min_obj_distance_/2.0));
+// if(infl > 0) std::for_each(from, to, [this](Item& item) {
+// item.inflate(infl);
+// });
- selector_.template packItems<PlacementStrategy>(
- from, to, bin_, pconfig_);
+// selector_.template packItems<PlacementStrategy>(
+// from, to, bin_, pconfig_);
- if(min_obj_distance_ > 0) std::for_each(from, to, [](Item& item) {
- item.inflate(-infl);
- });
- }
+// if(min_obj_distance_ > 0) std::for_each(from, to, [](Item& item) {
+// item.inflate(-infl);
+// });
+// }
};
}
diff --git a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
index 25007e580..f904210aa 100644
--- a/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
+++ b/src/libnest2d/include/libnest2d/selections/djd_heuristic.hpp
@@ -711,7 +711,12 @@ public:
addBin();
packjob(placers[idx], remaining, idx); idx++;
}
-
+
+ int binid = 0;
+ for(auto &bin : packed_bins_) {
+ for(Item& itm : bin) itm.binId(binid);
+ binid++;
+ }
}
};
diff --git a/src/libnest2d/include/libnest2d/selections/firstfit.hpp b/src/libnest2d/include/libnest2d/selections/firstfit.hpp
index 287204c08..6a3e2e61b 100644
--- a/src/libnest2d/include/libnest2d/selections/firstfit.hpp
+++ b/src/libnest2d/include/libnest2d/selections/firstfit.hpp
@@ -90,8 +90,10 @@ public:
size_t j = 0;
while(!was_packed && !cancelled()) {
for(; j < placers.size() && !was_packed && !cancelled(); j++) {
- if((was_packed = placers[j].pack(*it, rem(it, store_) )))
- makeProgress(placers[j], j);
+ if((was_packed = placers[j].pack(*it, rem(it, store_) ))) {
+ it->get().binId(int(j));
+ makeProgress(placers[j], j);
+ }
}
if(!was_packed) {
diff --git a/src/libnest2d/tests/test.cpp b/src/libnest2d/tests/test.cpp
index e5bd87182..6891b16e1 100644
--- a/src/libnest2d/tests/test.cpp
+++ b/src/libnest2d/tests/test.cpp
@@ -372,27 +372,34 @@ TEST(GeometryAlgorithms, ArrangeRectanglesTight)
Nester<BottomLeftPlacer, DJDHeuristic> arrange(bin);
- auto groups = arrange.execute(rects.begin(), rects.end());
-
- ASSERT_EQ(groups.size(), 1u);
- ASSERT_EQ(groups[0].size(), rects.size());
-
+ arrange.execute(rects.begin(), rects.end());
+
+ auto max_group = std::max_element(rects.begin(), rects.end(),
+ [](const Item &i1, const Item &i2) {
+ return i1.binId() < i2.binId();
+ });
+
+ int groups = max_group == rects.end() ? 0 : max_group->binId() + 1;
+
+ ASSERT_EQ(groups, 1u);
+ ASSERT_TRUE(
+ std::all_of(rects.begin(), rects.end(), [](const Rectangle &itm) {
+ return itm.binId() != BIN_ID_UNSET;
+ }));
+
// check for no intersections, no containment:
- for(auto result : groups) {
- bool valid = true;
- for(Item& r1 : result) {
- for(Item& r2 : result) {
- if(&r1 != &r2 ) {
- valid = !Item::intersects(r1, r2) || Item::touches(r1, r2);
- ASSERT_TRUE(valid);
- valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
- ASSERT_TRUE(valid);
- }
+ bool valid = true;
+ for(Item& r1 : rects) {
+ for(Item& r2 : rects) {
+ if(&r1 != &r2 ) {
+ valid = !Item::intersects(r1, r2) || Item::touches(r1, r2);
+ ASSERT_TRUE(valid);
+ valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
+ ASSERT_TRUE(valid);
}
}
}
-
}
TEST(GeometryAlgorithms, ArrangeRectanglesLoose)
@@ -433,16 +440,25 @@ TEST(GeometryAlgorithms, ArrangeRectanglesLoose)
Nester<BottomLeftPlacer, DJDHeuristic> arrange(bin, min_obj_distance);
- auto groups = arrange.execute(rects.begin(), rects.end());
+ arrange.execute(rects.begin(), rects.end());
+
+ auto max_group = std::max_element(rects.begin(), rects.end(),
+ [](const Item &i1, const Item &i2) {
+ return i1.binId() < i2.binId();
+ });
- ASSERT_EQ(groups.size(), 1u);
- ASSERT_EQ(groups[0].size(), rects.size());
+ size_t groups = max_group == rects.end() ? 0 : max_group->binId() + 1;
+
+ ASSERT_EQ(groups, 1u);
+ ASSERT_TRUE(
+ std::all_of(rects.begin(), rects.end(), [](const Rectangle &itm) {
+ return itm.binId() != BIN_ID_UNSET;
+ }));
// check for no intersections, no containment:
- auto result = groups[0];
bool valid = true;
- for(Item& r1 : result) {
- for(Item& r2 : result) {
+ for(Item& r1 : rects) {
+ for(Item& r2 : rects) {
if(&r1 != &r2 ) {
valid = !Item::intersects(r1, r2);
valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
@@ -554,27 +570,24 @@ TEST(GeometryAlgorithms, convexHull) {
TEST(GeometryAlgorithms, NestTest) {
std::vector<Item> input = prusaParts();
+
+ libnest2d::nest(input, Box(250000000, 210000000), [](unsigned cnt) {
+ std::cout << "parts left: " << cnt << std::endl;
+ });
+
+ auto max_binid_it = std::max_element(input.begin(), input.end(),
+ [](const Item &i1, const Item &i2) {
+ return i1.binId() < i2.binId();
+ });
+
+ size_t bins = max_binid_it == input.end() ? 0 : max_binid_it->binId() + 1;
- PackGroup result = libnest2d::nest(input,
- Box(250000000, 210000000),
- [](unsigned cnt) {
- std::cout
- << "parts left: " << cnt
- << std::endl;
- });
-
- ASSERT_LE(result.size(), 2);
-
- size_t partsum = std::accumulate(result.begin(),
- result.end(),
- size_t(0),
- [](size_t s,
- const decltype(
- result)::value_type &bin) {
- return s += bin.size();
- });
-
- ASSERT_EQ(input.size(), partsum);
+ ASSERT_EQ(bins, 2u);
+
+ ASSERT_TRUE(
+ std::all_of(input.begin(), input.end(), [](const Item &itm) {
+ return itm.binId() != BIN_ID_UNSET;
+ }));
}
namespace {