From 4676d87413b49a7dab63f6db51d0921f4d1fb5ad Mon Sep 17 00:00:00 2001 From: ganovelli Date: Thu, 8 Jul 2004 08:25:15 +0000 Subject: [PATCH] first draft --- vcg/complex/local_optimization.h | 248 +++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 vcg/complex/local_optimization.h diff --git a/vcg/complex/local_optimization.h b/vcg/complex/local_optimization.h new file mode 100644 index 00000000..f2af29a8 --- /dev/null +++ b/vcg/complex/local_optimization.h @@ -0,0 +1,248 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + $Log: not supported by cvs2svn $ +****************************************************************************/ + +#ifndef __VCGLIB_LOCALOPTIMIZATION +#define __VCGLIB_LOCALOPTIMIZATION +#include +#include +#include +#include + +namespace vcg{ +enum ModifierType{ TriEdgeCollapse, TriEdgeSwap, TriVertexSplit, + TetraEdgeCollapse,TetraEdgeSplit,TetraEdgeSwap}; + +/*@{*/ +/// This is an abstract class to define the interface of a local modification +template +class LocalModification +{ + + public: + LocalModification(){}; + ~LocalModification(){}; + + /// return the type of operation + virtual ModifierType IsOfType() = 0 ; + + /// return true if the data have not changed since it was created + virtual bool IsUpToDate() = 0 ; + + /// return true if no constraint disallow this operation to be performed (ex: change of topology in edge collapses) + virtual bool IsFeasible() = 0; + + /// Compute the priority to be used in the heap + virtual ScalarType ComputePriority()=0; + + /// Compute the error caused by this modification (can be the same as priority) + virtual ScalarType ComputeError()=0; + + /// Update the heap as a consequence of this operation + virtual void UpdateHeap(HeapType&)=0; + + /// Perform the operation + virtual void Execute()=0; +}; //end class local modification + + + +template +class LocalOptimization +{ +public: + LocalOptimization(){} + + struct HeapElem; + // scalar type + typedef typename MeshType::ScalarType ScalarType; + // type of the heap + typedef typename std::vector HeapType; + // modification type + typedef LocalModification LocModType; + // modification Pointer type + typedef LocalModification * LocModPtrType; + + + + /// termination conditions + enum { LOnSimplices = 0x00, // test number of simplicies + LOnVertices = 0x01, // test number of verticies + LOnOps = 0x02, // test number of operations + LOMetric = 0x04, // test Metric (error, quality...instance dependent) + LOTime = 0x08 // test how much time is passed since the start + } terminateFlags; + int nPerfmormedOps, + nTargetOps, + nTargetSimplices, + nTargetVertices; + + float timeBudget, + start, + currMetric, + targetMetric; + + void SetTerminationFlag (int v){tf |= v;} + void ClearTerminationFlag (int v){tf &= ~v;} + bool IsTerminationFlag (int v){return (tf & v);} + + void SetTargetSimplices (int ts ){nTargetSimplices = ts; SetTerminationFlag(LOnSimplices); } + void SetTargetVertices (int tv ){nTargetSimplices = tv; SetTerminationFlag(LOnVertices); } + void SetTargetOperations(int to ){nTargetOps = to; SetTerminationFlag(LOnOps); } + void SetTargetMetric (ScalarType tm ){targetMetric = tm; SetTerminationFlag(LOMetric); } + void SetTimeBudget (float tb ){timeBudget = tb; SetTerminationFlag(LOTime); } + + + /// the mesh to optimize + MeshType * m; + + + + ///the heap of operations + HeapType h; + + ///the element of the heap + struct HeapElem + { + ~HeapElem(){ + delete locModPtr; + } + + ///pointer to instance of local modifier + LocModPtrType locModPtr; + + ///temporary mark for the opration + int imark; + + HeapElem(const LocModPtrType _locModPtr, int _imark) + { + locModPtr = _locModPtr; + imark = _imark; + }; + + const bool operator <(const HeapElem & h) const + { + return (locModPtr->Priority()Priority()); + } + + bool IsUpToDate() + { + return locModPtr->IsUpToDate(imark); + + } +/* + if (!pos.T()->IsD()) + { + VertexType *v0=pos.T()->V(Tetra::VofE(pos.E(),0)); + VertexType *v1=pos.T()->V(Tetra::VofE(pos.E(),1)); + + return (( (!v0->IsD()) && (!v1->IsD())) && + Imark>=v0->IMark() && + Imark>=v1->IMark()); + } + else + return false; + } +*/ + + }; + + + + /// Default Constructor + LocalOptimization(MeshType &_m):m(_m){}; + /// Default distructor + ~LocalOptimization(){}; + + /// main cycle of optimization + void DoOptimization() + { + int i=0; + while( !GoalReached()) + { + if( ! h.back().IsUpToDate()) + h.pop_back(); // if it is out of date simply discard it + else + { + h.back().locModPtr->ComputeError(); + LocModPtrType LastMod= h.back().locModPtr; + h.pop_back(); + + // check if it is feasible + if (LastMod->IsFeasible()) + { + LastMod->Execute(); + LastMod->UpdateHeap(h); + } + } + } + } + + ///initialize for all vertex the temporary mark must call only at the start of decimation + void Init() + { + m.InitIMark(); + } + + + + + /// say if the process is to end or not: the process ends when any of the termination conditions is verified + /// override this function to implemetn other tests + bool GoalReached(){ + assert ( ( ( terminateFlags & LOnSimplices )==0) || ( nTargetSimplices!= -1)); + assert ( ( ( terminateFlags & LOnVertices )==0) || ( nTargetVertices != -1)); + assert ( ( ( terminateFlags & LOnOps )==0) || ( nTargetOps != -1)); + assert ( ( ( terminateFlags & LOMetric )==0) || ( targetMetric != -1)); + assert ( ( ( terminateFlags & LOTime )==0) || ( timeBudget != -1)); + + if ( ( terminateFlags & LOnSimplices) && ( m->SimplexNumber()< nTargetSimplices)) return true; + if ( ( terminateFlags & LOnVertices) && ( m->VertexNumber() < nTargetVertices)) return true; + if ( ( terminateFlags & LOnOps) && ( nPerfmormedOps == nTargetOps)) return true; + if ( ( terminateFlags & LOMetric) && ( currMetric > targetMetric)) return true; + if ( ( terminateFlags & LOTime) && ( (clock()-start)/(float)CLOCKS_PER_SEC > timeBudget)) return true; + } + + + +///erase from the heap the operations that are out of date + void ClearHeap() + { + typename HeapType::iterator hi; + for(hi=h.begin();hi!=h.end();++hi) + if(!(*hi)->LM->IsUpToDate()) + { + *hi=h.back(); + h.pop_back(); + if(hi==h.end()) break; + } + //printf("\nReduced heap from %i to %i",sz,h.size()); + make_heap(h.begin(),h.end()); + } + +};//end class decimation + +}//end namespace +#endif