local_optimization.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 /****************************************************************************
00024   $Log: not supported by cvs2svn $
00025   Revision 1.20  2007/01/19 09:13:09  cignoni
00026   Added Finalize() method to the interface
00027 
00028   Revision 1.19  2007/01/11 11:48:33  ganovelli
00029   currMetric inizialied to heap.front() (it was heap.back()- wrong)
00030 
00031   Revision 1.18  2006/12/11 14:09:44  ganovelli
00032   added missing initialization of currMetric
00033 
00034   Revision 1.17  2006/06/09 07:28:43  m_di_benedetto
00035   Corrected ClearHeap(): iterator "hi" not decrementable if it was the first of the container.
00036 
00037   Revision 1.16  2005/11/10 15:38:46  cignoni
00038   Added casts to remove warnings
00039 
00040   Revision 1.15  2005/10/02 23:23:52  cignoni
00041   Changed the sense of the < operator for heap: it is reversed according to the stl where highest score elements must float in the heap
00042   Completed TimeBudget Termination condition.
00043   Parametrized the ClearHeap procedure now there is a HeapSimplexRatio param. Removed dirty printf.
00044 
00045   Revision 1.14  2005/04/14 11:34:33  ponchio
00046   *** empty log message ***
00047 
00048   Revision 1.13  2005/01/19 10:33:50  cignoni
00049   Improved ClearHeap management
00050 
00051   Revision 1.12  2004/12/10 01:02:48  cignoni
00052   added an inline and removed loggng
00053 
00054   Revision 1.11  2004/12/03 21:14:39  ponchio
00055   Fixed memory leak...
00056 
00057   Revision 1.10  2004/11/23 10:37:17  cignoni
00058   Added a member with a cached copy of the floating Priority() value inside the HeapElem to optimize operator< in heap updating operator
00059 
00060   Revision 1.9  2004/11/05 10:03:47  fiorin
00061   Added ModifierType::TriEdgeFlipOp
00062 
00063   Revision 1.8  2004/10/25 07:02:56  ganovelli
00064   some inline function, logs on file (precompiler directive)
00065 
00066   Revision 1.7  2004/09/29 17:08:39  ganovelli
00067   changed > to < in heapelem comparison
00068 
00069   Revision 1.6  2004/09/28 09:57:08  cignoni
00070   Better Doxygen docs
00071 
00072   Revision 1.5  2004/09/15 10:40:20  ponchio
00073   typedef LocalOptimization HeapType -> public:
00074 
00075   Revision 1.4  2004/09/08 15:10:59  ganovelli
00076   *** empty log message ***
00077 
00078   Revision 1.3  2004/07/27 09:46:15  cignoni
00079   First working version of the LocalOptimization/Simplification Framework
00080 
00081   Revision 1.1  2004/07/15 12:04:14  ganovelli
00082   minor changes
00083 
00084   Revision 1.2  2004/07/09 10:22:56  ganovelli
00085   working draft
00086 
00087   Revision 1.1  2004/07/08 08:25:15  ganovelli
00088   first draft
00089 
00090 ****************************************************************************/
00091 
00092 #ifndef __VCGLIB_LOCALOPTIMIZATION
00093 #define __VCGLIB_LOCALOPTIMIZATION
00094 #include<vector>
00095 #include<algorithm>
00096 #include<time.h>
00097 #include<math.h>
00098 #include<vcg/complex/complex.h>
00099 
00100 namespace vcg{
00101 // Base class for Parameters
00102 // all parameters must be derived from this.
00103 class BaseParameterClass { };
00104 
00105 template<class MeshType>
00106 class LocalOptimization;
00107 
00108 enum ModifierType{      TetraEdgeCollapseOp, TriEdgeSwapOp, TriVertexSplitOp,
00109                                 TriEdgeCollapseOp,TetraEdgeSpliOpt,TetraEdgeSwapOp, TriEdgeFlipOp,
00110                                 QuadDiagCollapseOp, QuadEdgeCollapseOp};
00113 
00114 template <class MeshType>
00115 class LocalModification
00116 {
00117  public:
00118         typedef typename LocalOptimization<MeshType>::HeapType HeapType;
00119         typedef typename MeshType::ScalarType ScalarType;
00120 
00121 
00122   inline LocalModification(){}
00123   virtual ~LocalModification(){}
00124   
00126         virtual ModifierType IsOfType() = 0 ;
00127 
00129   virtual bool IsUpToDate() const = 0 ;
00130 
00132   virtual bool IsFeasible(BaseParameterClass *pp) = 0;
00133 
00135   virtual ScalarType ComputePriority(BaseParameterClass *pp)=0;
00136 
00138         virtual ScalarType Priority() const =0;
00139 
00141   virtual void Execute(MeshType &m, BaseParameterClass *pp)=0;
00142 
00144   static void Init(MeshType &m, HeapType&, BaseParameterClass *pp);
00145 
00151   static float HeapSimplexRatio(BaseParameterClass *) {return 6.0f;}
00152 
00153   virtual const char *Info(MeshType &) {return 0;}
00155   virtual void UpdateHeap(HeapType&, BaseParameterClass *pp)=0;
00156 };      //end class local modification
00157 
00158 
00165 
00166 template<class MeshType>
00167 class LocalOptimization
00168 {
00169 public:
00170   LocalOptimization(MeshType &mm, BaseParameterClass *_pp): m(mm){ ClearTermination();e=0.0;HeapSimplexRatio=5; pp=_pp;}
00171 
00172         struct  HeapElem;
00173         // scalar type
00174         typedef typename MeshType::ScalarType ScalarType;
00175         // type of the heap
00176         typedef typename std::vector<HeapElem> HeapType;        
00177         // modification type    
00178   typedef  LocalModification <MeshType>  LocModType;
00179         // modification Pointer type    
00180   typedef  LocalModification <MeshType> * LocModPtrType;
00181         
00182 
00183 
00185          enum LOTermination {   
00186       LOnSimplices      = 0x01, // test number of simplicies    
00187                         LOnVertices             = 0x02, // test number of verticies
00188                         LOnOps                  = 0x04, // test number of operations
00189                         LOMetric                = 0x08, // test Metric (error, quality...instance dependent)
00190                         LOTime                  = 0x10  // test how much time is passed since the start
00191                 } ;
00192 
00193         int tf;
00194         
00195   int nPerfmormedOps,
00196                 nTargetOps,
00197                 nTargetSimplices,
00198                 nTargetVertices;
00199 
00200         float   timeBudget;
00201   clock_t       start;
00202         ScalarType currMetric;
00203         ScalarType targetMetric;
00204   BaseParameterClass *pp;
00205 
00206   // The ratio between Heap size and the number of simplices in the current mesh
00207   // When this value is exceeded a ClearHeap Start;
00208 
00209   float HeapSimplexRatio; 
00210 
00211         void SetTerminationFlag         (int v){tf |= v;}
00212         void ClearTerminationFlag       (int v){tf &= ~v;}
00213         bool IsTerminationFlag          (int v){return ((tf & v)!=0);}
00214 
00215         void SetTargetSimplices (int ts                 ){nTargetSimplices      = ts;   SetTerminationFlag(LOnSimplices);       }               
00216         void SetTargetVertices  (int tv                 ){nTargetVertices       = tv;   SetTerminationFlag(LOnVertices);        } 
00217         void SetTargetOperations(int to                 ){nTargetOps            = to;   SetTerminationFlag(LOnOps);                     } 
00218 
00219         void SetTargetMetric    (ScalarType tm  ){targetMetric          = tm;   SetTerminationFlag(LOMetric);           } 
00220         void SetTimeBudget              (float tb               ){timeBudget            = tb;   SetTerminationFlag(LOTime);                     } 
00221 
00222   void ClearTermination()
00223   {
00224     tf=0;
00225     nTargetSimplices=0;
00226     nTargetOps=0;
00227     targetMetric=0;
00228     timeBudget=0;
00229     nTargetVertices=0;
00230   }
00232         MeshType & m;
00233 
00234 
00235 
00237         HeapType h;
00238 
00240   // it is just a wrapper of the pointer to the localMod. 
00241   // std heap does not work for
00242   // pointers and we want pointers to have heterogenous heaps. 
00243 
00244   struct HeapElem
00245   {
00246                 inline HeapElem(){locModPtr = NULL;}
00247           ~HeapElem(){}
00248 
00250     LocModPtrType locModPtr;
00251     float pri;
00252 
00253    
00254     inline HeapElem( LocModPtrType _locModPtr)
00255     {
00256                   locModPtr = _locModPtr;
00257       pri=float(locModPtr->Priority());
00258     };
00259 
00262     inline bool operator <(const HeapElem & h) const
00263     { 
00264                   return (pri > h.pri);
00265                   //return (locModPtr->Priority() < h.locModPtr->Priority());
00266           }
00267 
00268     bool IsUpToDate() const
00269     {
00270                         return locModPtr->IsUpToDate();
00271                 }
00272   };
00273 
00274 
00275 
00277   ~LocalOptimization(){ 
00278     typename HeapType::iterator i;
00279     for(i = h.begin(); i != h.end(); i++)
00280       delete (*i).locModPtr;
00281   };
00282         
00283         double e;
00284 
00286   bool DoOptimization()
00287   {
00288     start=clock();
00289                 nPerfmormedOps =0;
00290                 while( !GoalReached() && !h.empty())
00291                         {
00292         if(h.size()> m.SimplexNumber()*HeapSimplexRatio )  ClearHeap();
00293                                 std::pop_heap(h.begin(),h.end());
00294         LocModPtrType  locMod   = h.back().locModPtr;
00295                                 currMetric=h.back().pri;
00296         h.pop_back();
00297                                         
00298         if( locMod->IsUpToDate() )
00299                                 {       
00300           //printf("popped out: %s\n",locMod->Info(m));
00301                 // check if it is feasible
00302           if (locMod->IsFeasible(this->pp))
00303                                         {
00304                                                 nPerfmormedOps++;
00305             locMod->Execute(m,this->pp);
00306             locMod->UpdateHeap(h,this->pp);
00307                                                 }
00308                                 }
00309         //else printf("popped out unfeasible\n");
00310                                 delete locMod;
00311                         }
00312                 return !(h.empty());
00313   }
00314  
00315 // It removes from the heap all the operations that are no more 'uptodate' 
00316 // (e.g. collapses that have some recently modified vertices)
00317 // This function  is called from time to time by the doOptimization (e.g. when the heap is larger than fn*3)
00318 void ClearHeap()
00319 {
00320         typename HeapType::iterator hi;
00321         //int sz=h.size();
00322         for(hi=h.begin();hi!=h.end();)
00323         {
00324     if(!(*hi).locModPtr->IsUpToDate())
00325                 {
00326                         delete (*hi).locModPtr;
00327                         *hi=h.back();
00328                         if(&*hi==&h.back()) 
00329                         {
00330                                 hi=h.end();
00331                                 h.pop_back();
00332                                 break;
00333                         }
00334                     h.pop_back();
00335                         continue;
00336                 }
00337                 ++hi;
00338         }
00339         //qDebug("\nReduced heap from %7i to %7i (fn %7i) ",sz,h.size(),m.fn);
00340         make_heap(h.begin(),h.end());
00341 }
00342 
00346   template <class LocalModificationType> void Init()
00347         {
00348     vcg::tri::InitVertexIMark(m);
00349                 
00350     // The expected size of heap depends on the type of the local modification we are using..
00351     HeapSimplexRatio = LocalModificationType::HeapSimplexRatio(pp);
00352                 
00353     LocalModificationType::Init(m,h,pp);
00354     std::make_heap(h.begin(),h.end());
00355     if(!h.empty()) currMetric=h.front().pri;
00356         }
00357 
00358 
00359         template <class LocalModificationType> void Finalize()
00360         {
00361     LocalModificationType::Finalize(m,h,pp);
00362         }
00363 
00364 
00367         bool GoalReached(){
00368                 assert ( ( ( tf & LOnSimplices  )==0) ||  ( nTargetSimplices!= -1));
00369                 assert ( ( ( tf & LOnVertices   )==0) ||  ( nTargetVertices     != -1));
00370                 assert ( ( ( tf & LOnOps                )==0) ||  ( nTargetOps          != -1));
00371                 assert ( ( ( tf & LOMetric              )==0) ||  ( targetMetric        != -1));
00372                 assert ( ( ( tf & LOTime                )==0) ||  ( timeBudget          != -1));
00373 
00374                 if ( IsTerminationFlag(LOnSimplices) && ( m.SimplexNumber()<= nTargetSimplices)) return true;
00375                 if ( IsTerminationFlag(LOnVertices)  &&  ( m.VertexNumber() <= nTargetVertices)) return true;
00376                 if ( IsTerminationFlag(LOnOps)             && (nPerfmormedOps   == nTargetOps)) return true;
00377                 if ( IsTerminationFlag(LOMetric)                 &&  ( currMetric               > targetMetric)) return true;
00378     if ( IsTerminationFlag(LOTime) )
00379     {
00380       clock_t cur = clock();
00381       if(cur<start) // overflow of tick counter;
00382         return true; // panic
00383       else
00384        if ( (cur - start)/(double)CLOCKS_PER_SEC > timeBudget) return true;
00385     }
00386                 return false;
00387         }
00388 
00389 
00390 
00392   void ClearHeapOld()
00393   {
00394                 typename HeapType::iterator hi;
00395                 for(hi=h.begin();hi!=h.end();++hi)
00396                         if(!(*hi).locModPtr->IsUpToDate())
00397                         {
00398                                 *hi=h.back();
00399                                 h.pop_back();
00400                                 if(hi==h.end()) break;
00401                         }
00402                         //printf("\nReduced heap from %i to %i",sz,h.size());
00403                         make_heap(h.begin(),h.end());
00404   }
00405 
00406 };//end class decimation
00407 
00408 }//end namespace
00409 #endif


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