MaxRectsBinPack.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /** @file MaxRectsBinPack.h
  2. @author Jukka Jylänki
  3. @brief Implements different bin packer algorithms that use the MAXRECTS data structure.
  4. This work is released to Public Domain, do whatever you want with it.
  5. */
  6. #pragma once
  7. #include "Rect.h"
  8. /** MaxRectsBinPack implements the MAXRECTS data structure and different bin packing algorithms that
  9. use this structure. */
  10. class MaxRectsBinPack
  11. {
  12. public:
  13. /// Instantiates a bin of size (0,0). Call Init to create a new bin.
  14. MaxRectsBinPack();
  15. /// Instantiates a bin of the given size.
  16. MaxRectsBinPack(int width, int height, bool allowRotate);
  17. /// (Re)initializes the packer to an empty bin of width x height units. Call whenever
  18. /// you need to restart with a new bin.
  19. void Init(int width, int height, bool allowRotate);
  20. /// Specifies the different heuristic rules that can be used when deciding where to place a new rectangle.
  21. enum FreeRectChoiceHeuristic
  22. {
  23. RectBestShortSideFit, ///< -BSSF: Positions the rectangle against the short side of a free rectangle into which it fits the best.
  24. RectBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best.
  25. RectBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits.
  26. RectBottomLeftRule, ///< -BL: Does the Tetris placement.
  27. RectContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible.
  28. };
  29. /// Inserts the given list of rectangles in an offline/batch mode, possibly rotated.
  30. /// @param rects The list of rectangles to insert. This vector will be destroyed in the process.
  31. /// @param dst [out] This list will contain the packed rectangles. The indices will not correspond to that of rects.
  32. /// @param method The rectangle placement rule to use when packing.
  33. void Insert(MemPtr<RectSizeIndex> rects, MemPtr<RectIndex> dst, FreeRectChoiceHeuristic method);
  34. /// Inserts a single rectangle into the bin, possibly rotated.
  35. Rect Insert(int width, int height, FreeRectChoiceHeuristic method);
  36. /// Computes the ratio of used surface area to the total bin area.
  37. float Occupancy() const;
  38. private:
  39. int binWidth;
  40. int binHeight;
  41. bool allowRotate;
  42. Memc<Rect> usedRectangles;
  43. Memc<Rect> freeRectangles;
  44. /// Computes the placement score for placing the given rectangle with the given method.
  45. /// @param score1 [out] The primary placement score will be outputted here.
  46. /// @param score2 [out] The secondary placement score will be outputted here. This isu sed to break ties.
  47. /// @return This struct identifies where the rectangle would be placed if it were placed.
  48. Rect ScoreRect(int width, int height, FreeRectChoiceHeuristic method, int &score1, int &score2) const;
  49. /// Places the given rectangle into the bin.
  50. void PlaceRect(const Rect &node);
  51. /// Computes the placement score for the -CP variant.
  52. int ContactPointScoreNode(int x, int y, int width, int height) const;
  53. Rect FindPositionForNewNodeBottomLeft(int width, int height, int &bestY, int &bestX) const;
  54. Rect FindPositionForNewNodeBestShortSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
  55. Rect FindPositionForNewNodeBestLongSideFit(int width, int height, int &bestShortSideFit, int &bestLongSideFit) const;
  56. Rect FindPositionForNewNodeBestAreaFit(int width, int height, int &bestAreaFit, int &bestShortSideFit) const;
  57. Rect FindPositionForNewNodeContactPoint(int width, int height, int &contactScore) const;
  58. /// @return True if the free node was split.
  59. bool SplitFreeNode(Rect freeNode, const Rect &usedNode);
  60. void SplitFreeRects(const Rect &usedNode);
  61. /// Goes through the free rectangle list and removes any redundant entries.
  62. void PruneFreeList();
  63. };