Commits

Lars Viklund committed 6d59cb1

Change MAXRECTS heuristic to CP, disallow rotations

  • Participants
  • Parent commits 7481fc5

Comments (0)

Files changed (1)

Katla/src/layout.cc

 // vim: ts=4 sw=4 et cin
 
 #include <cstring>
+#include <deque>
 #include <iostream>
 #include <ostream>
 #include <map>
 
 std::ostream& operator << (std::ostream& os, AlgorithmInput const& input);
 
-AlgorithmOutput MAXRECTS_BSSF_BNF(AlgorithmInput input);
+AlgorithmOutput MAXRECTS_CP(AlgorithmInput input);
 
 AlgorithmOutput Homogeneous(AlgorithmInput input);
 void WriteOutput(std::ostream& os, AlgorithmOutput const& out);
         char const* val = json_string_value(algorithm);
         if (! strcmp(val, "homogeneous"))
             input.algorithm = val;
-        else if (! strcmp(val, "clb-maxrects-bssf-bnf"))
+        else if (! strcmp(val, "clb-maxrects-cp"))
             input.algorithm = val;
         else
             missing.push_back("algorithm");
     AlgorithmOutput output;
     if (input.algorithm == "homogeneous")
         output = Homogeneous(input);
-    else if (input.algorithm == "clb-maxrects-bssf-bnf")
-        output = MAXRECTS_BSSF_BNF(input);
+    else if (input.algorithm == "clb-maxrects-cp")
+        output = MAXRECTS_CP(input);
     else
     {
         return 3;
     }
 };
 
-AlgorithmOutput MAXRECTS_BSSF_BNF(AlgorithmInput input)
+AlgorithmOutput MAXRECTS_CP(AlgorithmInput input)
 {
     AlgorithmOutput output;
 
         Group const& group = I->second;
         int w = input.maxDimension, h = input.maxDimension;
         int serial = 0;
-        TilemapDesc desc = {};
-        desc.filename = BuildTilemapPath(input.tilemapBasename, ch, serial++);
-        desc.width = w;
-        desc.height = h;
-        desc.channels = ch;
-
-        MaxRectsBinPack packer(input.maxDimension, input.maxDimension);
+        TilemapDesc descTemplate = {};
+        descTemplate.filename = BuildTilemapPath(input.tilemapBasename, ch, serial++);
+        descTemplate.width = w;
+        descTemplate.height = h;
+        descTemplate.channels = ch;
+
+        MaxRectsBinPack::FreeRectChoiceHeuristic heuristic = MaxRectsBinPack::RectContactPointRule;
+
+        std::deque<MaxRectsBinPack> packers;
+        std::deque<TilemapDesc> descs;
+        packers.push_back(MaxRectsBinPack(input.maxDimension, input.maxDimension));
+        descs.push_back(descTemplate);
         for (Group::const_iterator J = group.begin();
              J != group.end();
-             /* missing increment intentional*/)
+             ++J)
         {
-            Rect r = packer.Insert(J->width, J->height, MaxRectsBinPack::RectBestShortSideFit);
-            if (r.height == J->height)
+            bool foundHome = false;
+            std::deque<MaxRectsBinPack>::iterator K = packers.begin();
+            std::deque<TilemapDesc>::iterator L = descs.begin();
+            for (/* initialization intentionally missing */;
+                 K != packers.end() && L != descs.end() && !foundHome;
+                 ++K, ++L)
             {
-                desc.images.push_back(*J);
-                TileInfo tile = { r.x, r.y };
-                desc.tiles.push_back(tile);
-                ++J;
+                Rect r = K->Insert(J->width, J->height, heuristic, false);
+                if (r.height == J->height)
+                {
+                    TilemapDesc& desc = *L;
+                    desc.images.push_back(*J);
+                    TileInfo tile = { r.x, r.y };
+                    desc.tiles.push_back(tile);
+                    foundHome = true;
+                }
             }
-            else
+            if (!foundHome)
             {
-                output.tilemaps.push_back(desc);
+                MaxRectsBinPack packer(input.maxDimension, input.maxDimension);
+                TilemapDesc desc = descTemplate;
                 desc.filename = BuildTilemapPath(input.tilemapBasename, ch, serial++);
-                desc.images.clear();
-                desc.tiles.clear();
-                packer.Init(input.maxDimension, input.maxDimension);
+                Rect r = packer.Insert(J->width, J->height, heuristic, false);
+                desc.images.push_back(*J);
+                TileInfo tile = { r.x, r.y };
+                desc.tiles.push_back(tile);
+
+                packers.push_back(packer);
+                descs.push_back(desc);
             }
         }
-        if (packer.Occupancy())
-        {
-            output.tilemaps.push_back(desc);
-        }
+        output.tilemaps.insert(output.tilemaps.end(), descs.begin(), descs.end());
     }
     return output;
 }
 void Usage()
 {
     std::cerr << "Input file format - JSON object with the following fields:\n"
-        "  algorithm: \"homogeneous\" (req)\n"
+        "  algorithm: \"homogeneous | clb-maxrects-cp\" (req)\n"
         "  output_power_of_two: boolean (req)\n"
         "  max_dimension: integer (req)\n"
         "  images: list of files (req)\n"