From 7d2b7b9ba77bc4c0fbd60383e12f3d82aa9498a2 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Wed, 16 Feb 2022 13:25:22 +0100 Subject: [PATCH] fix naive packer --- README.md | 3 +-- src/main_gui.cpp | 27 +++++++++++++++++++-------- src/pack.cpp | 22 ++++++++++++++++------ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index aef7c00..3cb1ca0 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ The subject is available here: [Test Algo](./test_algo.pdf) - [ ] skyline - [X] add raygui - [X] resize box -- [ ] add box in gui by pressing down -- [ ] delete box in gui by clicking +- [X] delete box in gui by clicking - [ ] wrap stb_rect_pack? - [X] change bbox api to origin + size - [ ] dummy A2 diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 2409ddc..e218a30 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -119,8 +119,10 @@ int main(int argc, const char* argv[]) { const Vector2 b_size = {150, 30}; Vector2 mouse_pos = {0}; Vector2 mouse_delta = {0}; - int b_moving_idx = -1; - int b_resize_idx = -1; + constexpr int idx_unset = -1; + int b_moving_idx = idx_unset; + int b_resize_idx = idx_unset; + int b_delete_idx = idx_unset; while (!WindowShouldClose()) { // @@ -131,8 +133,10 @@ int main(int argc, const char* argv[]) { for (int b = 0, size = bboxes.size(); b < size; ++b) { const auto& box = bboxes[b]; const Rectangle rect = rect_from_bbox(box, in_offset); - if (CheckCollisionPointRec(mouse_pos, rect) and - IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + if (not CheckCollisionPointRec(mouse_pos, rect)) { + continue; + } + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { const Rectangle handle_area = { rect.x + rect.width - resize_handle, rect.y + rect.height - resize_handle, resize_handle, @@ -143,23 +147,30 @@ int main(int argc, const char* argv[]) { b_moving_idx = b; } } + if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) { + b_delete_idx = b; + } } if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) { - b_moving_idx = -1; - b_resize_idx = -1; + b_moving_idx = idx_unset; + b_resize_idx = idx_unset; } - if (b_moving_idx != -1) { + if (b_moving_idx != idx_unset) { auto& box = bboxes[b_moving_idx]; box.x += mouse_delta.x; box.y += mouse_delta.y; } - if (b_resize_idx != -1) { + if (b_resize_idx != idx_unset) { auto& box = bboxes[b_resize_idx]; box.width = std::max(static_cast(box.width + mouse_delta.x), resize_handle); box.height = std::max(static_cast(box.height + mouse_delta.y), resize_handle); } + if (b_delete_idx != idx_unset) { + bboxes.erase(bboxes.begin() + b_delete_idx); + b_delete_idx = idx_unset; + } // // Draw diff --git a/src/pack.cpp b/src/pack.cpp index ea39870..9b922ea 100644 --- a/src/pack.cpp +++ b/src/pack.cpp @@ -57,18 +57,17 @@ std::optional pack(const Frame& in_frame, int max_area = 0; for (const auto& box : sorted_bboxes) { int area = box.area(); - std::cout << "bounding box area: " << area << "\n"; max_area += area; } - std::cout << "max area: " << max_area << "\n"; + std::cout << "[pack] max area: " << max_area << "\n"; int optimal_size = int(ceil(std::sqrt(max_area))); - std::cout << "optimal image dimention: " << optimal_size << " x " + std::cout << "[pack] optimal image dimention: " << optimal_size << " x " << optimal_size << "\n"; // cf. subject: D < min(M, N ) const int max_size = std::min(in_frame.width, in_frame.height) - 1; - std::cout << "maximum image dimention: " << max_size << " x " << max_size - << "\n"; + std::cout << "[pack] maximum image dimention: " << max_size << " x " + << max_size << "\n"; // We will try to fit all the rectangles in a given square of size S. // optimal_size <= S <= max_size (smallest dimension of input frame) @@ -76,6 +75,8 @@ std::optional pack(const Frame& in_frame, const int nb_candidates = 5; const int size_increment = (max_size - optimal_size) / nb_candidates; for (int size = optimal_size; size <= max_size; size += size_increment) { + std::cout << "[pack] trying to fit in " << size << " x " << size + << "\n"; int x = 0; int y = 0; int next_row = 0; @@ -84,16 +85,23 @@ std::optional pack(const Frame& in_frame, for (int box_i = 0, box_max = bboxes.size(); room_left and box_i < box_max; ++box_i) { auto& box = sorted_bboxes[box_i]; + std::cout << "[pack] box " << box.width << " x " << box.height + << "\n"; // If we don't have room in either dimension, we won't be able to // pack within this size candidate. - if (x + box.width >= size or y + box.height >= size) { + if (x + box.width >= size and next_row + box.height >= size) { + std::cout << "[pack] -> no room left (last row height = " + << size - y << ")\n"; room_left = false; continue; } // If we cannot fit the rect on the right, we fit it below. if (x + box.width >= size) { + std::cout + << "[pack] -> cannot fit in current row (width left = " + << size - x << ")\n"; x = 0; y = next_row; } @@ -103,11 +111,13 @@ std::optional pack(const Frame& in_frame, // know the next ones won't cross this line. if (x == 0) { next_row = box.height; + std::cout << "[pack] -> create new row at line " << y << "\n"; } box.x = x; box.y = y; x += box.width; + std::cout << "[pack] -> fit in (" << x << ", " << y << ")\n"; } if (room_left) {