From 5e501264a17b592d033ca190ca931b1ba4cb59e6 Mon Sep 17 00:00:00 2001 From: Mark Tyberg Date: Mon, 23 Sep 2019 13:02:23 -0400 Subject: [PATCH 1/4] added allowFlip flag to GuillotineBinPack --- GuillotineBinPack.cpp | 17 +++++++++-------- GuillotineBinPack.h | 8 +++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/GuillotineBinPack.cpp b/GuillotineBinPack.cpp index 3cc8755..be42d79 100644 --- a/GuillotineBinPack.cpp +++ b/GuillotineBinPack.cpp @@ -1,5 +1,5 @@ /** @file GuillotineBinPack.cpp - @author Jukka Jylänki + @author Jukka Jyl�nki @brief Implements different bin packer algorithms that use the GUILLOTINE data structure. @@ -25,15 +25,16 @@ binHeight(0) { } -GuillotineBinPack::GuillotineBinPack(int width, int height) +GuillotineBinPack::GuillotineBinPack(int width, int height, bool allowFlip) { - Init(width, height); + Init(width, height, allowFlip); } -void GuillotineBinPack::Init(int width, int height) +void GuillotineBinPack::Init(int width, int height, bool allowFlip) { binWidth = width; binHeight = height; + binAllowFlip = allowFlip; #ifdef _DEBUG disjointRects.Clear(); @@ -83,7 +84,7 @@ void GuillotineBinPack::Insert(std::vector &rects, bool merge, break; } // If flipping this rectangle is a perfect match, pick that then. - else if (rects[j].height == freeRectangles[i].width && rects[j].width == freeRectangles[i].height) + else if (binAllowFlip && rects[j].height == freeRectangles[i].width && rects[j].width == freeRectangles[i].height) { bestFreeRect = i; bestRect = j; @@ -105,7 +106,7 @@ void GuillotineBinPack::Insert(std::vector &rects, bool merge, } } // If not, then perhaps flipping sideways will make it fit? - else if (rects[j].height <= freeRectangles[i].width && rects[j].width <= freeRectangles[i].height) + else if (binAllowFlip && rects[j].height <= freeRectangles[i].width && rects[j].width <= freeRectangles[i].height) { int score = ScoreByHeuristic(rects[j].height, rects[j].width, freeRectangles[i], rectChoice); if (score < bestScore) @@ -450,7 +451,7 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh break; } // If this is a perfect fit sideways, choose it. - else if (height == freeRectangles[i].width && width == freeRectangles[i].height) + else if (binAllowFlip && height == freeRectangles[i].width && width == freeRectangles[i].height) { bestNode.x = freeRectangles[i].x; bestNode.y = freeRectangles[i].y; @@ -478,7 +479,7 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh } } // Does the rectangle fit sideways? - else if (height <= freeRectangles[i].width && width <= freeRectangles[i].height) + else if (binAllowFlip && height <= freeRectangles[i].width && width <= freeRectangles[i].height) { int score = ScoreByHeuristic(height, width, freeRectangles[i], rectChoice); diff --git a/GuillotineBinPack.h b/GuillotineBinPack.h index 66ff2c9..884b250 100644 --- a/GuillotineBinPack.h +++ b/GuillotineBinPack.h @@ -1,5 +1,5 @@ /** @file GuillotineBinPack.h - @author Jukka Jylänki + @author Jukka Jyl�nki @brief Implements different bin packer algorithms that use the GUILLOTINE data structure. @@ -22,11 +22,11 @@ class GuillotineBinPack GuillotineBinPack(); /// Initializes a new bin of the given size. - GuillotineBinPack(int width, int height); + GuillotineBinPack(int width, int height, bool allowFlip = true); /// (Re)initializes the packer to an empty bin of width x height units. Call whenever /// you need to restart with a new bin. - void Init(int width, int height); + void Init(int width, int height, bool allowFlip = true); /// Specifies the different choice heuristics that can be used when deciding which of the free subrectangles /// to place the to-be-packed rectangle into. @@ -92,6 +92,8 @@ class GuillotineBinPack int binWidth; int binHeight; + bool binAllowFlip; + /// Stores a list of all the rectangles that we have packed so far. This is used only to compute the Occupancy ratio, /// so if you want to have the packer consume less memory, this can be removed. std::vector usedRectangles; From 00eb5b7e346d47f31b596bc77b56e6aee1b14f8f Mon Sep 17 00:00:00 2001 From: Mark Tyberg Date: Tue, 24 Sep 2019 15:53:23 -0400 Subject: [PATCH 2/4] updating formatting --- GuillotineBinPack.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/GuillotineBinPack.cpp b/GuillotineBinPack.cpp index be42d79..45ef3c0 100644 --- a/GuillotineBinPack.cpp +++ b/GuillotineBinPack.cpp @@ -19,9 +19,7 @@ namespace rbp { using namespace std; -GuillotineBinPack::GuillotineBinPack() -:binWidth(0), -binHeight(0) +GuillotineBinPack::GuillotineBinPack() : binWidth(0), binHeight(0) { } @@ -34,7 +32,7 @@ void GuillotineBinPack::Init(int width, int height, bool allowFlip) { binWidth = width; binHeight = height; - binAllowFlip = allowFlip; + binAllowFlip = allowFlip; #ifdef _DEBUG disjointRects.Clear(); From 735b40e9857d35244a14dd874d75e7ed64b77d73 Mon Sep 17 00:00:00 2001 From: Mark Tyberg Date: Wed, 25 Sep 2019 12:35:16 -0400 Subject: [PATCH 3/4] fixed windows build --- GuillotineBinPack.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/GuillotineBinPack.cpp b/GuillotineBinPack.cpp index 45ef3c0..350c492 100644 --- a/GuillotineBinPack.cpp +++ b/GuillotineBinPack.cpp @@ -5,6 +5,7 @@ This work is released to Public Domain, do whatever you want with it. */ +#include #include #include #include From 57385f4abe22dfb79ba36f09987b15b8d45d49d6 Mon Sep 17 00:00:00 2001 From: Mark Tyberg Date: Wed, 7 Apr 2021 17:00:12 -0400 Subject: [PATCH 4/4] removed debugging code --- GuillotineBinPack.cpp | 26 -------------------------- GuillotineBinPack.h | 5 ----- 2 files changed, 31 deletions(-) diff --git a/GuillotineBinPack.cpp b/GuillotineBinPack.cpp index 350c492..c3c4ae6 100644 --- a/GuillotineBinPack.cpp +++ b/GuillotineBinPack.cpp @@ -35,10 +35,6 @@ void GuillotineBinPack::Init(int width, int height, bool allowFlip) binHeight = height; binAllowFlip = allowFlip; -#ifdef _DEBUG - disjointRects.Clear(); -#endif - // Clear any memory of previously packed rectangles. usedRectangles.clear(); @@ -147,8 +143,6 @@ void GuillotineBinPack::Insert(std::vector &rects, bool merge, // Remember the new used rectangle. usedRectangles.push_back(newNode); - // Check that we're really producing correct packings here. - debug_assert(disjointRects.Add(newNode) == true); } } @@ -358,9 +352,6 @@ Rect GuillotineBinPack::Insert(int width, int height, bool merge, FreeRectChoice // Remember the new used rectangle. usedRectangles.push_back(newRect); - // Check that we're really producing correct packings here. - debug_assert(disjointRects.Add(newRect) == true); - return newRect; } @@ -446,7 +437,6 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh bestNode.height = height; bestScore = std::numeric_limits::min(); *nodeIndex = i; - debug_assert(disjointRects.Disjoint(bestNode)); break; } // If this is a perfect fit sideways, choose it. @@ -458,7 +448,6 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh bestNode.height = width; bestScore = std::numeric_limits::min(); *nodeIndex = i; - debug_assert(disjointRects.Disjoint(bestNode)); break; } // Does the rectangle fit upright? @@ -474,7 +463,6 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh bestNode.height = height; bestScore = score; *nodeIndex = i; - debug_assert(disjointRects.Disjoint(bestNode)); } } // Does the rectangle fit sideways? @@ -490,7 +478,6 @@ Rect GuillotineBinPack::FindPositionForNewNode(int width, int height, FreeRectCh bestNode.height = width; bestScore = score; *nodeIndex = i; - debug_assert(disjointRects.Disjoint(bestNode)); } } } @@ -579,18 +566,10 @@ void GuillotineBinPack::SplitFreeRectAlongAxis(const Rect &freeRect, const Rect if (right.width > 0 && right.height > 0) freeRectangles.push_back(right); - debug_assert(disjointRects.Disjoint(bottom)); - debug_assert(disjointRects.Disjoint(right)); } void GuillotineBinPack::MergeFreeList() { -#ifdef _DEBUG - DisjointRectCollection test; - for(size_t i = 0; i < freeRectangles.size(); ++i) - assert(test.Add(freeRectangles[i]) == true); -#endif - // Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one. // Note that we miss any opportunities to merge three rectangles into one. (should call this function again to detect that) for(size_t i = 0; i < freeRectangles.size(); ++i) @@ -630,11 +609,6 @@ void GuillotineBinPack::MergeFreeList() } } -#ifdef _DEBUG - test.Clear(); - for(size_t i = 0; i < freeRectangles.size(); ++i) - assert(test.Add(freeRectangles[i]) == true); -#endif } } diff --git a/GuillotineBinPack.h b/GuillotineBinPack.h index 884b250..84aa866 100644 --- a/GuillotineBinPack.h +++ b/GuillotineBinPack.h @@ -101,11 +101,6 @@ class GuillotineBinPack /// Stores a list of rectangles that represents the free area of the bin. This rectangles in this list are disjoint. std::vector freeRectangles; -#ifdef _DEBUG - /// Used to track that the packer produces proper packings. - DisjointRectCollection disjointRects; -#endif - /// Goes through the list of free rectangles and finds the best one to place a rectangle of given size into. /// Running time is Theta(|freeRectangles|). /// @param nodeIndex [out] The index of the free rectangle in the freeRectangles array into which the new