outline2_packer.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 #ifndef __VCG_OUTLINE2_PACKER_H__
00024 #define __VCG_OUTLINE2_PACKER_H__
00025 
00026 #include <limits>
00027 #include <stdio.h>
00028 #include <assert.h>
00029 #include <algorithm>
00030 #include <vector>
00031 #include <vcg/space/box2.h>
00032 #include <vcg/space/rect_packer.h>
00033 #include <vcg/space/point2.h>
00034 #include <vcg/math/similarity2.h>
00035 
00036 
00037 
00038 namespace vcg
00039 {
00040 
00041 template <class SCALAR_TYPE>
00042 class PolyPacker
00043 {
00044   typedef typename vcg::Box2<SCALAR_TYPE> Box2x;
00045   typedef typename vcg::Point2<SCALAR_TYPE> Point2x;
00046   typedef typename vcg::Similarity2<SCALAR_TYPE> Similarity2x;
00047 
00048 public:
00049 
00050   static Box2f getPolyBB(const std::vector<Point2x> &poly)
00051   {
00052     Box2f bb;
00053     for(size_t i=0;i<poly.size();++i)
00054       bb.Add(poly[i]);
00055 
00056     return bb;
00057   }
00058 
00059   static Box2f getPolyOOBB(const std::vector<Point2x> &poly, float &rot)
00060   {
00061     const int stepNum=32;
00062     float bestAngle;
00063     float bestArea = std::numeric_limits<float>::max();
00064     Box2f bestBB;
00065 
00066     for(int i=0;i<stepNum;++i)
00067     {
00068       float angle = float(i)*(M_PI/2.0)/float(stepNum);
00069       Box2f bb;
00070       for(size_t j=0;j<poly.size();++j)
00071       {
00072         Point2f pp=poly[j];
00073         pp.Rotate(angle);
00074         bb.Add(pp);
00075       }
00076 
00077       if(bb.Area()<bestArea)
00078       {
00079         bestAngle=angle;
00080         bestArea=bb.Area();
00081         bestBB=bb;
00082       }
00083     }
00084     rot=bestAngle;
00085     return bestBB;
00086   }
00087 
00088 static  bool PackAsEqualSquares(const std::vector< std::vector<Point2x> > &polyVec,
00089                   const Point2i containerSizeX,
00090                   std::vector<Similarity2x> &trVec,
00091                   Point2x &coveredContainer)
00092 {
00093   int minSide = std::min(containerSizeX[0],containerSizeX[1]);
00094   const vcg::Point2i containerSize(minSide,minSide);
00095   int polyPerLine = ceil(sqrt((double)polyVec.size()));
00096   int pixelPerPoly = minSide / (polyPerLine);
00097   if(pixelPerPoly < 1) return false;
00098 
00099   trVec.clear();
00100   trVec.resize(polyVec.size());
00101   Box2f bbMax;
00102   std::vector<Box2x> bbVec;
00103   for(size_t i=0;i<polyVec.size();++i)
00104   {
00105     bbVec.push_back(getPolyBB(polyVec[i]));
00106     bbMax.Add(bbVec.back());
00107   }
00108 
00109   float unitScale = 1.0/std::max(bbMax.DimX(), bbMax.DimY());
00110   float polyScale = unitScale * pixelPerPoly;
00111 
00112   int baseX =0;
00113   int baseY=0;
00114   for(size_t i=0;i<polyVec.size();++i)
00115   {
00116     trVec[i].sca = polyScale; // the same scaling for all the polygons;
00117     trVec[i].tra = Point2f(baseX+(0.5*pixelPerPoly), baseY+(0.5*pixelPerPoly)) - bbVec[i].Center()*polyScale;
00118     baseX +=pixelPerPoly;
00119 
00120     if(baseX +pixelPerPoly>minSide)
00121     {
00122       baseY+=pixelPerPoly;
00123       baseX=0;
00124     }
00125   }
00126   return true;
00127 }
00128 
00129 static bool PackAsAxisAlignedRect(const std::vector< std::vector<Point2x> > &polyVec,
00130                   const Point2i containerSizeX,
00131                   std::vector<Similarity2x> &trVec,
00132                   Point2x &coveredContainer)
00133 {
00134   trVec.clear();
00135   trVec.resize(polyVec.size());
00136   std::vector<Box2x> bbVec;
00137   for(size_t i=0;i<polyVec.size();++i)
00138   {
00139     assert(polyVec[i].size()>0);
00140     bbVec.push_back(getPolyBB(polyVec[i]));
00141   }
00142   return RectPacker<float>::Pack(bbVec,containerSizeX,trVec,coveredContainer);
00143 }
00144 
00145 static bool PackAsObjectOrientedRect(const std::vector< std::vector<Point2x> > &polyVec,
00146                   const Point2i containerSizeX,
00147                   std::vector<Similarity2x> &trVec,
00148                   Point2x &coveredContainer)
00149 {
00150   trVec.clear();
00151   trVec.resize(polyVec.size());
00152   std::vector<Box2x> bbVec;
00153   std::vector<float> rotVec;
00154   for(size_t i=0;i<polyVec.size();++i)
00155   {
00156     float rot;
00157     bbVec.push_back(getPolyOOBB(polyVec[i],rot));
00158     rotVec.push_back(rot);
00159   }
00160 
00161   bool ret= RectPacker<float>::Pack(bbVec,containerSizeX,trVec,coveredContainer);
00162 
00163   for(size_t i=0;i<polyVec.size();++i)
00164   {
00165     trVec[i].rotRad=rotVec[i];
00166   }
00167   return ret;
00168 }
00169 
00170 
00171 static bool PackMultiAsObjectOrientedRect(const std::vector< std::vector<Point2x> > &polyVec,
00172                   const Point2x containerSizeX, const int containerNum,
00173                   std::vector<Similarity2x> &trVec, std::vector<int> &indVec,
00174                   std::vector<Point2x> &coveredContainerVec)
00175 {
00176   trVec.clear();
00177   trVec.resize(polyVec.size());
00178   std::vector<Box2x> bbVec;
00179   std::vector<float> rotVec;
00180   for(size_t i=0;i<polyVec.size();++i)
00181   {
00182     float rot;
00183     bbVec.push_back(getPolyOOBB(polyVec[i],rot));
00184     rotVec.push_back(rot);
00185   }
00186   const Point2i containerSizeI=Point2i::Construct(containerSizeX);
00187   bool ret= RectPacker<float>::PackMulti(bbVec,containerSizeI,containerNum,trVec,indVec,coveredContainerVec);
00188 
00189   for(size_t i=0;i<polyVec.size();++i)
00190   {
00191     trVec[i].rotRad=rotVec[i];
00192   }
00193   return ret;
00194 }
00195 
00196 static bool WritePolyVec(const std::vector< std::vector<Point2x> > &polyVec, const char *filename)
00197 {
00198   FILE *fp=fopen(filename,"w");
00199   if(!fp) return false;
00200   fprintf(fp,"%lu\n",polyVec.size());
00201   for(size_t i=0;i<polyVec.size();++i)
00202   {
00203     fprintf(fp,"%lu\n",polyVec[i].size());
00204     for(size_t j=0;j<polyVec[i].size();++j)
00205       fprintf(fp,"%f %f ",polyVec[i][j].X(),polyVec[i][j].Y());
00206     fprintf(fp,"\n");
00207   }
00208   fclose(fp);
00209   return true;
00210 }
00211 
00212 static bool ReadPolyVec(std::vector< std::vector<Point2x> > &polyVec, const char *filename)
00213 {
00214   FILE *fp=fopen(filename,"r");
00215   if(!fp) return false;
00216   int sz;
00217   fscanf(fp,"%i\n",&sz);
00218   polyVec.clear();
00219   polyVec.resize(sz);
00220   for(size_t i=0;i<polyVec.size();++i)
00221   {
00222     fscanf(fp,"%i\n",&sz);
00223     polyVec[i].resize(sz);
00224     for(size_t j=0;j<polyVec[i].size();++j)
00225     {
00226       float x,y;
00227       fscanf(fp,"%f %f",&x,&y);
00228       polyVec[i][j].X()=x;
00229       polyVec[i][j].Y()=y;
00230     }
00231   }
00232   fclose(fp);
00233   return true;
00234 }
00235 
00236 
00237 }; // end class
00238 } // end namespace vcg
00239 #endif // POLY_PACKER_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:34