00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
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/trimesh/base.h>
00099
00100 namespace vcg{
00101
00102 template<class MeshType>
00103 class LocalOptimization;
00104
00105 enum ModifierType{ TetraEdgeCollapseOp, TriEdgeSwapOp, TriVertexSplitOp,
00106 TriEdgeCollapseOp,TetraEdgeSpliOpt,TetraEdgeSwapOp, TriEdgeFlipOp};
00109
00110 template <class MeshType>
00111 class LocalModification
00112 {
00113 public:
00114 typedef typename LocalOptimization<MeshType>::HeapType HeapType;
00115 typedef typename MeshType::ScalarType ScalarType;
00116
00117
00118 inline LocalModification(){};
00119 virtual ~LocalModification(){};
00120
00122 virtual ModifierType IsOfType() = 0 ;
00123
00125 virtual bool IsUpToDate() = 0 ;
00126
00128 virtual bool IsFeasible() = 0;
00129
00131 virtual ScalarType ComputePriority()=0;
00132
00134 virtual ScalarType Priority() const =0;
00135
00137 virtual void Execute(MeshType &m)=0;
00138
00140 static void Init(MeshType &m, HeapType&);
00141
00147 static float HeapSimplexRatio() {return 6.0f;} ;
00148
00149 virtual const char *Info(MeshType &) {return 0;}
00151 virtual void UpdateHeap(HeapType&)=0;
00152 };
00153
00154
00161
00162 template<class MeshType>
00163 class LocalOptimization
00164 {
00165 public:
00166 LocalOptimization(MeshType &mm): m(mm){ ClearTermination();e=0.0;HeapSimplexRatio=5;}
00167
00168 struct HeapElem;
00169
00170 typedef typename MeshType::ScalarType ScalarType;
00171
00172 typedef typename std::vector<HeapElem> HeapType;
00173
00174 typedef LocalModification <MeshType> LocModType;
00175
00176 typedef LocalModification <MeshType> * LocModPtrType;
00177
00178
00179
00181 enum LOTermination {
00182 LOnSimplices = 0x01,
00183 LOnVertices = 0x02,
00184 LOnOps = 0x04,
00185 LOMetric = 0x08,
00186 LOTime = 0x10
00187 } ;
00188
00189 int tf;
00190
00191 int nPerfmormedOps,
00192 nTargetOps,
00193 nTargetSimplices,
00194 nTargetVertices;
00195
00196 float timeBudget;
00197 int start;
00198 ScalarType currMetric;
00199 ScalarType targetMetric;
00200
00201
00202
00203
00204 float HeapSimplexRatio;
00205
00206 void SetTerminationFlag (int v){tf |= v;}
00207 void ClearTerminationFlag (int v){tf &= ~v;}
00208 bool IsTerminationFlag (int v){return ((tf & v)!=0);}
00209
00210 void SetTargetSimplices (int ts ){nTargetSimplices = ts; SetTerminationFlag(LOnSimplices); }
00211 void SetTargetVertices (int tv ){nTargetVertices = tv; SetTerminationFlag(LOnVertices); }
00212 void SetTargetOperations(int to ){nTargetOps = to; SetTerminationFlag(LOnOps); }
00213
00214 void SetTargetMetric (ScalarType tm ){targetMetric = tm; SetTerminationFlag(LOMetric); }
00215 void SetTimeBudget (float tb ){timeBudget = tb; SetTerminationFlag(LOTime); }
00216
00217 void ClearTermination()
00218 {
00219 tf=0;
00220 nTargetSimplices=0;
00221 nTargetOps=0;
00222 targetMetric=0;
00223 timeBudget=0;
00224 nTargetVertices=0;
00225 }
00227 MeshType & m;
00228
00229
00230
00232 HeapType h;
00233
00235
00236
00237
00238
00239 struct HeapElem
00240 {
00241 inline HeapElem(){locModPtr = NULL;}
00242 ~HeapElem(){}
00243
00245 LocModPtrType locModPtr;
00246 float pri;
00247
00248
00249 inline HeapElem( LocModPtrType _locModPtr)
00250 {
00251 locModPtr = _locModPtr;
00252 pri=float(locModPtr->Priority());
00253 };
00254
00257 inline const bool operator <(const HeapElem & h) const
00258 {
00259 return (pri > h.pri);
00260
00261 }
00262
00263 bool IsUpToDate()
00264 {
00265 return locModPtr->IsUpToDate();
00266 }
00267 };
00268
00269
00270
00272 ~LocalOptimization(){
00273 typename HeapType::iterator i;
00274 for(i = h.begin(); i != h.end(); i++)
00275 delete (*i).locModPtr;
00276 };
00277
00278 double e;
00279
00281 bool DoOptimization()
00282 {
00283 start=clock();
00284 nPerfmormedOps =0;
00285 while( !GoalReached() && !h.empty())
00286 {
00287 if(h.size()> m.SimplexNumber()*HeapSimplexRatio ) ClearHeap();
00288 std::pop_heap(h.begin(),h.end());
00289 LocModPtrType locMod = h.back().locModPtr;
00290 currMetric=h.back().pri;
00291 h.pop_back();
00292
00293 if( locMod->IsUpToDate() )
00294 {
00295
00296
00297 if (locMod->IsFeasible())
00298 {
00299 nPerfmormedOps++;
00300 locMod->Execute(m);
00301 locMod->UpdateHeap(h);
00302 }
00303 }
00304
00305 delete locMod;
00306 }
00307 return !(h.empty());
00308 }
00309
00310
00311
00312
00313 void ClearHeap()
00314 {
00315 typename HeapType::iterator hi;
00316
00317 for(hi=h.begin();hi!=h.end();)
00318 {
00319 if(!(*hi).locModPtr->IsUpToDate())
00320 {
00321 delete (*hi).locModPtr;
00322 *hi=h.back();
00323 if(&*hi==&h.back())
00324 {
00325 hi=h.end();
00326 h.pop_back();
00327 break;
00328 }
00329 h.pop_back();
00330 continue;
00331 }
00332 ++hi;
00333 }
00334
00335 make_heap(h.begin(),h.end());
00336 }
00337
00341 template <class LocalModificationType> void Init()
00342 {
00343 vcg::tri::InitVertexIMark(m);
00344
00345
00346 HeapSimplexRatio = LocalModificationType::HeapSimplexRatio();
00347
00348 LocalModificationType::Init(m,h);
00349 std::make_heap(h.begin(),h.end());
00350 if(!h.empty()) currMetric=h.front().pri;
00351 }
00352
00353
00354 template <class LocalModificationType> void Finalize()
00355 {
00356 LocalModificationType::Finalize(m,h);
00357 }
00358
00359
00362 bool GoalReached(){
00363 assert ( ( ( tf & LOnSimplices )==0) || ( nTargetSimplices!= -1));
00364 assert ( ( ( tf & LOnVertices )==0) || ( nTargetVertices != -1));
00365 assert ( ( ( tf & LOnOps )==0) || ( nTargetOps != -1));
00366 assert ( ( ( tf & LOMetric )==0) || ( targetMetric != -1));
00367 assert ( ( ( tf & LOTime )==0) || ( timeBudget != -1));
00368
00369 if ( IsTerminationFlag(LOnSimplices) && ( m.SimplexNumber()<= nTargetSimplices)) return true;
00370 if ( IsTerminationFlag(LOnVertices) && ( m.VertexNumber() <= nTargetVertices)) return true;
00371 if ( IsTerminationFlag(LOnOps) && (nPerfmormedOps == nTargetOps)) return true;
00372 if ( IsTerminationFlag(LOMetric) && ( currMetric > targetMetric)) return true;
00373 if ( IsTerminationFlag(LOTime) && ( (clock()-start)/(float)CLOCKS_PER_SEC > timeBudget)) return true;
00374 return false;
00375 }
00376
00377
00378
00380 void ClearHeapOld()
00381 {
00382 typename HeapType::iterator hi;
00383 for(hi=h.begin();hi!=h.end();++hi)
00384 if(!(*hi).locModPtr->IsUpToDate())
00385 {
00386 *hi=h.back();
00387 h.pop_back();
00388 if(hi==h.end()) break;
00389 }
00390
00391 make_heap(h.begin(),h.end());
00392 }
00393
00394 };
00395
00396 }
00397 #endif