Attempts to merge rects adjacent rects in a set, returns the number merged. This keeps looping until
| 61 | // Attempts to merge rects adjacent rects in a set, returns the number merged. |
| 62 | // This keeps looping until |
| 63 | static unsigned compactRectSet(std::set<Rect<T>> &rectSet) |
| 64 | { |
| 65 | unsigned merged = 0; |
| 66 | restart: |
| 67 | for (auto it1 = rectSet.begin(); it1 != rectSet.end();) |
| 68 | { |
| 69 | auto rect1 = *it1++; |
| 70 | for (auto it2 = rectSet.begin(); it2 != rectSet.end();) |
| 71 | { |
| 72 | auto rect2 = *it2++; |
| 73 | if (rect1 == rect2) |
| 74 | continue; |
| 75 | auto rect1Size = rect1.size(); |
| 76 | auto rect2Size = rect2.size(); |
| 77 | bool canMerge = false; |
| 78 | // Can merge rects where r1 lines up to r2 in x |
| 79 | // |
| 80 | // +----+ |
| 81 | // | r1 | |
| 82 | // +----+ |
| 83 | // | r2 | |
| 84 | // +----+ |
| 85 | // |
| 86 | // or in y |
| 87 | // +----+----+ |
| 88 | // | r1 | r2 | |
| 89 | // +----+----+ |
| 90 | // |
| 91 | // No need to check other way as r1 & r2 will be compared in both orders in the |
| 92 | // loop |
| 93 | // |
| 94 | if (rect1Size.x == rect2Size.x && rect1.p0.x == rect2.p0.x && |
| 95 | rect1.p1.y == rect2.p0.y) |
| 96 | { |
| 97 | canMerge = true; |
| 98 | } |
| 99 | if (rect1Size.y == rect2Size.y && rect1.p0.y == rect2.p0.y && |
| 100 | rect1.p1.x == rect2.p0.x) |
| 101 | { |
| 102 | canMerge = true; |
| 103 | } |
| 104 | if (canMerge) |
| 105 | { |
| 106 | Rect<T> mergedRect{rect1.p0, rect2.p1}; |
| 107 | rectSet.erase(rect1); |
| 108 | rectSet.erase(rect2); |
| 109 | rectSet.insert(mergedRect); |
| 110 | merged++; |
| 111 | goto restart; |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | return merged; |
| 116 | } |
| 117 | }; |
| 118 | |
| 119 | template <typename T> std::ostream &operator<<(std::ostream &lhs, const OpenApoc::Rect<T> &rhs) |