diff --git a/vcg/complex/tetramesh/decimation/collapse.h b/vcg/complex/tetramesh/decimation/collapse.h index 2acabb72..141b16b9 100644 --- a/vcg/complex/tetramesh/decimation/collapse.h +++ b/vcg/complex/tetramesh/decimation/collapse.h @@ -26,8 +26,9 @@ #ifndef __VCG_DECIMATION_COLLAPSE #define __VCG_DECIMATION_COLLAPSE -#include + #include +#include namespace vcg{ @@ -35,10 +36,13 @@ namespace tetra{ /** \addtogroup tetramesh */ /*@{*/ -/// This Class is specialization for the edge collapse +/// This Class is specialization of LocalModification for the edge collapse +/// It wraps the atomic operation EdgeCollapse to be used in a optimizatin routine. +/// Note that it has knowledge of the heap of the class LocalOptimization because +/// it is responsible of updating it after a collapse has been performed template -class Collapse: public vcg::tetra::LocalModification +class Collapse: public LocalOptimization::LocModType { /// The tetrahedral mesh type @@ -57,40 +61,37 @@ class Collapse: public vcg::tetra::LocalModification typedef Pos PosType; /// The HEdgePos Loop type typedef PosLoop PosLType; - - + /// definition of the heap element + typedef typename LocalOptimization::HeapElem HeapElem; private: ///the new point that substitute the edge Point3 _NewPoint; ///the pointer to edge collapser method -vcg::tetra::EdgeCollapse *_EC; +vcg::tetra::EdgeCollapse _EC; ///mark for up_dating -char _Imark; +int _Imark; ///the pos of collapse PosType pos; ///pointer to vertex that remain VertexType *vrem; +/// priority in the heap +ScalarType _priority; + public: /// Default Constructor Collapse() - { - _EC=NULL; - } + {} ///Constructor with postype - Collapse(PosType p) - { - /* Imark=mark;*/ + Collapse(PosType p,int mark) + { + _Imark = mark; pos=p; - _EC=NULL; } ~Collapse() - { - if (_EC!=NULL) - delete(_EC); - } + {} private: @@ -135,14 +136,14 @@ ScalarType _VolumePreservingError(PosType &pos,CoordType &new_point,int nsteps) if ((ext_v0)&&(ext_v1))//both are external vertex { ScalarType step=1.f/(nsteps-1); - ScalarType Vol_Original=_EC->VolumeOriginal(); + ScalarType Vol_Original=_EC.VolumeOriginal(); for (int i=0;iP()*alfatemp) +(ve1->P()*(1.f-alfatemp)); //the error is the absolute value of difference of volumes - ScalarType error=fabs(Vol_Original-_EC->VolumeSimulateCollapse(pos,newPTemp)); + ScalarType error=fabs(Vol_Original-_EC.VolumeSimulateCollapse(pos,newPTemp)); if(errorpos)); + return (_priority = _AspectRatioMedia(this->pos)); } ScalarType ComputeError() { - if (_EC==NULL) - { - _EC=new vcg::tetra::EdgeCollapse(); - _EC->FindSets(pos); - } + _EC.FindSets(pos); return (_VolumePreservingError(pos,_NewPoint,5)); } - void Execute() + int Execute() { - if (_EC==NULL) - { - _EC=new vcg::tetra::EdgeCollapse(); - _EC->FindSets(pos); - } - _EC->DoCollapse(pos,_NewPoint); + _EC.FindSets(pos); + return -_EC.DoCollapse(pos,_NewPoint); } - bool PreserveTopology() - { - if (_EC==NULL) - { - _EC=new vcg::tetra::EdgeCollapse(); - _EC->FindSets(pos); - } - return(_EC->CheckPreconditions(pos,_NewPoint)); - } - HeapRetType UpdateHeap() + void UpdateHeap(LocalOptimization::HeapType & h_ret) { - HeapRetType h_ret; assert(!vrem->IsD()); VTIterator VTi(vrem->VTb(),vrem->VTi()); while (!VTi.End()) @@ -203,13 +186,50 @@ public: for (int j=0;j<6;j++) { vcg::tetra::Pos p=Pos(VTi.Vt(),Tetra::FofE(j,0),j,Tetra::VofE(j,0)); - h_ret.push_back(HeapRetElem(vcg::tetra::MTEdgeCollapse,p)); + h_ret.push_back(HeapElem(new Collapse(p,_Imark))); } VTi++; } - return (h_ret); } + ModifierType IsOfType(){ return TetraEdgeCollapse;} + + bool IsFeasible(){ + _EC.FindSets(pos); + return(_EC.CheckPreconditions(pos,_NewPoint)); + } + + bool IsUpToDate(){ + 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; + } + + virtual ScalarType Priority(){ + return _priority; + } + + virtual void Init(TetraMeshType&m,LocalOptimization::HeapType&h_ret){ + h_ret.clear(); + TetraMeshType::TetraIterator ti; + int j; + for(ti = m.tetra.begin(); ti != m.tetra.end();++ti) + for (int j=0;j<6;j++) + { + PosType p=PosType(&*ti,Tetra::FofE(j,0),j,Tetra::VofE(j,0)); + h_ret.push_back(HeapElem(new Collapse(p,m.IMark))); + } + + } + }; }//end namespace tetra }//end namespace vcg