From e977c746bd9a447eead08a74c6113f250852f86b Mon Sep 17 00:00:00 2001 From: Matteo Dellepiane Date: Tue, 29 Nov 2016 11:37:19 +0100 Subject: [PATCH] PackInt function made public In order to make the new Ponchio's nexus work properly --- vcg/space/rect_packer.h | 284 ++++++++++++++++++++-------------------- 1 file changed, 142 insertions(+), 142 deletions(-) diff --git a/vcg/space/rect_packer.h b/vcg/space/rect_packer.h index d5033a3a..d56bc144 100644 --- a/vcg/space/rect_packer.h +++ b/vcg/space/rect_packer.h @@ -240,6 +240,148 @@ static bool PackOccupancyMulti(const std::vector & rectVec, /// the se return true; } +/* This is the low level function that packs a set of int rects onto a grid. + +Based on the criptic code written by Claudio Rocchini + +Greedy algorithm. +Sort the rect according their height (larger first) +and then place them in the position that minimize the area of the bbox of all the placed rectangles + +To efficiently skip occupied areas it fills the grid with the id of the already placed rectangles. +*/ +static bool PackInt(const std::vector & sizes, // the sizes of the rect to be packed + const vcg::Point2i & max_size, // the size of the container + std::vector & posiz, // the found positionsof each rect + vcg::Point2i & global_size) // the size of smallest rect covering all the packed rect +{ + int n = (int)(sizes.size()); + assert(n>0 && max_size[0]>0 && max_size[1]>0); + + int gridSize = max_size[0] * max_size[1]; // Size dell griglia + int i, j, x, y; + + posiz.resize(n, Point2i(-1, -1)); + std::vector grid(gridSize, 0); // Creazione griglia + +#define Grid(q,w) (grid[(q)+(w)*max_size[0]]) + + // Build a permutation that keeps the reordiering of the sizes vector according to their width + std::vector perm(n); + for (i = 0; imax_size[0] || sizes[perm[0]][1]>max_size[1]) + return false; + + // Posiziono il primo + j = perm[0]; + global_size = sizes[j]; + posiz[j] = Point2i(0, 0); + + // Fill the grid with the id(+1) of the first + for (y = 0; y= 0 && x= 0 && y= 0 && j0 && sy>0); + + // Calcolo la posizione limite + int lx = std::min(global_size[0], max_size[0] - sx); + int ly = std::min(global_size[1], max_size[1] - sy); + + assert(lx>0 && ly>0); + + int finterior = 0; + + for (y = 0; y <= ly; y++) + { + for (x = 0; x <= lx;) + { + int px; + int c = Grid(x, y + sy - 1); + // Intersection check + if (!c) c = Grid(x + sx - 1, y + sy - 1); + if (!c) + { + for (px = x; px= 0 && carea) + { + bestx = x; + besty = y; + bestsx = nsx; + bestsy = nsy; + bestArea = area; + if (bestsx == global_size[0] && bestsy == global_size[1]) + finterior = 1; + } + break; + } + if (finterior) break; + } + if (finterior) break; + } + + if (bestArea == -1) + { + return false; + } + + posiz[j][0] = bestx; + posiz[j][1] = besty; + global_size[0] = bestsx; + global_size[1] = bestsy; + for (y = posiz[j][1]; y= 0 && x= 0 && y & sizes, // the sizes of the rect to be packed - const vcg::Point2i & max_size, // the size of the container - std::vector & posiz, // the found positionsof each rect - vcg::Point2i & global_size) // the size of smallest rect covering all the packed rect -{ - int n = (int)(sizes.size()); - assert(n>0 && max_size[0]>0 && max_size[1]>0); - - int gridSize = max_size[0]*max_size[1]; // Size dell griglia - int i,j,x,y; - - posiz.resize(n,Point2i(-1,-1)); - std::vector grid(gridSize,0); // Creazione griglia - - #define Grid(q,w) (grid[(q)+(w)*max_size[0]]) - - // Build a permutation that keeps the reordiering of the sizes vector according to their width - std::vector perm(n); - for(i=0;imax_size[0] || sizes[perm[0]][1]>max_size[1] ) - return false; - - // Posiziono il primo - j = perm[0]; - global_size = sizes[j]; - posiz[j] = Point2i(0,0); - - // Fill the grid with the id(+1) of the first - for(y=0;y=0 && x=0 && y=0 && j0 && sy>0); - - // Calcolo la posizione limite - int lx = std::min(global_size[0],max_size[0]-sx); - int ly = std::min(global_size[1],max_size[1]-sy); - - assert(lx>0 && ly>0); - - int finterior = 0; - - for(y=0;y<=ly;y++) - { - for(x=0;x<=lx;) - { - int px; - int c = Grid(x,y+sy-1); - // Intersection check - if(!c) c = Grid(x+sx-1,y+sy-1); - if(!c) - { - for(px=x;px=0 && carea) - { - bestx = x; - besty = y; - bestsx = nsx; - bestsy = nsy; - bestArea = area; - if( bestsx==global_size[0] && bestsy==global_size[1] ) - finterior = 1; - } - break; - } - if(finterior) break; - } - if( finterior ) break; - } - - if(bestArea==-1) - { - return false; - } - - posiz[j][0] = bestx; - posiz[j][1] = besty; - global_size[0] = bestsx; - global_size[1] = bestsy; - for(y=posiz[j][1];y=0 && x=0 && y & sizes, const int ntexture,