Skip to content

Commit 2f53fac

Browse files
committed
Templatize the input subjects to easily hold metadata #14
1 parent 3344bf5 commit 2f53fac

4 files changed

Lines changed: 76 additions & 13 deletions

File tree

example/main.cpp

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <iostream>
2+
#include <list>
23
#include <rectpack2D/finders_interface.h>
34

45
/* For description of the algorithm, please see the README.md */
@@ -75,13 +76,56 @@ int main() {
7576

7677
const auto discard_step = -4;
7778

79+
/*
80+
Your custom class holding the rectangle.
81+
82+
If you do not need any data associated with the rectangles,
83+
you are free to ignore this class and just use an std::vector<rect_type>.
84+
*/
85+
86+
class my_rect {
87+
rect_type rect;
88+
int some_medadata = 0;
89+
90+
public:
91+
my_rect(const rect_type& rect) : rect(rect) { (void)some_medadata; }
92+
93+
/*
94+
You need to provide these two member getters.
95+
96+
The algorithm has to extract the actual rectangles
97+
from your custom class. They will be modified in-place.
98+
99+
*/
100+
101+
auto& get_rect() {
102+
return rect;
103+
}
104+
105+
const auto& get_rect() const {
106+
return rect;
107+
}
108+
};
109+
78110
/*
79111
Create some arbitrary rectangles.
80112
Every subsequent call to the packer library will only read the widths and heights that we now specify,
81113
and always overwrite the x and y coordinates with calculated results.
82114
*/
83115

84-
std::vector<rect_type> rectangles;
116+
std::vector<my_rect> rectangles;
117+
118+
/*
119+
The example will compile just fine if you any of these instead:
120+
121+
std::vector<rect_type> rectangles;
122+
std::list<rect_type> rectangles;
123+
124+
std::list<my_rect> rectangles;
125+
126+
1. The container just needs to be forward-iterable with .begin() and .end().
127+
2. The element type just needs to have get_rect() member functions defined (const and non-const).
128+
*/
85129

86130
rectangles.emplace_back(rect_xywh(0, 0, 20, 40));
87131
rectangles.emplace_back(rect_xywh(0, 0, 120, 40));
@@ -92,7 +136,8 @@ int main() {
92136
auto report_result = [&rectangles](const rect_wh& result_size) {
93137
std::cout << "Resultant bin: " << result_size.w << " " << result_size.h << std::endl;
94138

95-
for (const auto& r : rectangles) {
139+
for (const auto& rect : rectangles) {
140+
const auto& r = rect.get_rect();
96141
std::cout << r.x << " " << r.y << " " << r.w << " " << r.h << std::endl;
97142
}
98143
};
@@ -175,7 +220,7 @@ int main() {
175220
packing_root.flipping_mode = runtime_flipping_mode;
176221

177222
for (auto& r : rectangles) {
178-
if (const auto inserted_rectangle = packing_root.insert(std::as_const(r).get_wh())) {
223+
if (const auto inserted_rectangle = packing_root.insert(std::as_const(r.get_rect()).get_wh())) {
179224
r = *inserted_rectangle;
180225
}
181226
else {

src/rectpack2D/best_bin_finder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ namespace rectpack2D {
8989

9090
const bool all_inserted = [&]() {
9191
for (const auto& r : ordering) {
92-
const auto& rect = dereference(r);
92+
const auto& rect = dereference(r).get_rect();
9393

9494
if (root.insert(rect.get_wh())) {
9595
total_inserted_area += rect.area();
@@ -264,7 +264,7 @@ namespace rectpack2D {
264264
root.reset(best_bin);
265265

266266
for (auto& rr : *best_order) {
267-
auto& rect = dereference(rr);
267+
auto& rect = dereference(rr).get_rect();
268268

269269
if (const auto ret = root.insert(rect.get_wh())) {
270270
rect = *ret;

src/rectpack2D/finders_interface.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ namespace rectpack2D {
4646
just in the order that they were passed.
4747
*/
4848

49-
template <class empty_spaces_type, class F, class G>
49+
template <class empty_spaces_type, class Subjects, class F, class G>
5050
rect_wh find_best_packing_dont_sort(
51-
std::vector<output_rect_t<empty_spaces_type>>& subjects,
51+
Subjects& subjects,
5252
const finder_input<F, G>& input
5353
) {
5454
using order_type = std::remove_reference_t<decltype(subjects)>;
@@ -68,9 +68,9 @@ namespace rectpack2D {
6868
and will only write the x, y coordinates of the best packing found among the orders.
6969
*/
7070

71-
template <class empty_spaces_type, class F, class G, class Comparator, class... Comparators>
71+
template <class empty_spaces_type, class Subjects, class F, class G, class Comparator, class... Comparators>
7272
rect_wh find_best_packing(
73-
std::vector<output_rect_t<empty_spaces_type>>& subjects,
73+
Subjects& subjects,
7474
const finder_input<F, G>& input,
7575

7676
Comparator comparator,
@@ -88,8 +88,10 @@ namespace rectpack2D {
8888
initial_pointers.clear();
8989

9090
for (auto& s : subjects) {
91-
if (s.area() > 0) {
92-
initial_pointers.emplace_back(std::addressof(s));
91+
auto& r = s.get_rect();
92+
93+
if (r.area() > 0) {
94+
initial_pointers.emplace_back(std::addressof(r));
9395
}
9496
}
9597

@@ -121,9 +123,9 @@ namespace rectpack2D {
121123
Provides a list of several sensible comparison predicates.
122124
*/
123125

124-
template <class empty_spaces_type, class F, class G>
126+
template <class empty_spaces_type, class Subjects, class F, class G>
125127
rect_wh find_best_packing(
126-
std::vector<output_rect_t<empty_spaces_type>>& subjects,
128+
Subjects& subjects,
127129
const finder_input<F, G>& input
128130
) {
129131
using rect_type = output_rect_t<empty_spaces_type>;

src/rectpack2D/rect_structs.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ namespace rectpack2D {
4949
auto get_wh() const {
5050
return rect_wh(w, h);
5151
}
52+
53+
auto& get_rect() {
54+
return *this;
55+
}
56+
57+
const auto& get_rect() const {
58+
return *this;
59+
}
5260
};
5361

5462
struct rect_xywhf {
@@ -68,6 +76,14 @@ namespace rectpack2D {
6876
auto get_wh() const {
6977
return rect_wh(w, h);
7078
}
79+
80+
auto& get_rect() {
81+
return *this;
82+
}
83+
84+
const auto& get_rect() const {
85+
return *this;
86+
}
7187
};
7288

7389
using space_rect = rect_xywh;

0 commit comments

Comments
 (0)