/**************************************************************************** * 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. * * * ****************************************************************************/ /**************************************************************************** History ****************************************************************************/ #ifndef __VCG_DECIMATION_TRICOLLAPSE #define __VCG_DECIMATION_CTRIOLLAPSE #include #include #include struct FAIL{ static VOL(){static int vol=0; return vol++;} static LKF(){static int lkf=0; return lkf++;} static LKE(){static int lke=0; return lke++;} static LKV(){static int lkv=0; return lkv++;} static OFD(){static int ofd=0; return ofd++;} static BOR(){static int bor=0; return bor++;} }; namespace vcg{ namespace tri{ /** \addtogroup trimesh */ /*@{*/ /// 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 TriEdgeCollapse: public LocalOptimization::LocModType { /// The tetrahedral mesh type typedef typename TRI_MESH_TYPE TriMeshType; /// The tetrahedron type typedef typename TriMeshType::FaceType FaceType; /// The vertex type typedef typename FaceType::VertexType VertexType; /// The coordinate type typedef typename FaceType::VertexType::CoordType CoordType; /// The scalar type typedef typename TriMeshType::VertexType::ScalarType ScalarType; /////the base type class //typedef typename vcg::tri::LocalModification LocalMod; /// The HEdgePos type typedef vcg::face::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 EdgeCollapse _EC; ///mark for up_dating static int& _Imark(){ static int im=0; return im;} ///the pos of collapse PosType pos; ///pointer to vertex that remain VertexType *vrem; /// priority in the heap ScalarType _priority; public: /// Default Constructor TriEdgeCollapse() {} ///Constructor with postype TriEdgeCollapse(PosType p,int mark) { _Imark() = mark; pos=p; _priority = _AspectRatioMedia(p); } ~TriEdgeCollapse() {} private: ///Return the aspect Ratio media of the tetrahedrons ///that share the adge to collapse ScalarType _AspectRatioMedia(PosType p) { /* PosLType posl=PosLType(p.T(),p.F(),p.E(),p.V()); posl.Reset(); int num=0; ScalarType ratio_media=0.f; while(!posl.LoopEnd()) { ratio_media+=posl.T()->AspectRatio(); posl.NextT(); num++; } ratio_media=ratio_media/num; return (ratio_media);*/ } ///Modify pos and alfa to obtain the collapse that minimize the error ScalarType _VolumePreservingError(PosType &pos,CoordType &new_point,int nsteps) { //VertexType *ve0=(pos.T()->V(Tetra::VofE(pos.E(),0))); //VertexType *ve1=(pos.T()->V(Tetra::VofE(pos.E(),1))); //vrem =ve0; //bool ext_v0=ve0->IsB(); //bool ext_v1=ve1->IsB(); //ScalarType best_error=0.f; // if ((ext_v0)&&(!ext_v1)) // new_point=ve0->P(); // else // if ((!ext_v0)&&(ext_v1)) // new_point=ve1->P(); // else // if ((!ext_v0)&&(!ext_v1)) // new_point=(ve0->P()+ve1->P())/2.f; // else // if ((ext_v0)&&(ext_v1))//both are external vertex // { // ScalarType step=1.f/(nsteps-1); // 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)); // if(error::HeapType & h_ret) { _Imark()++; vcg::face::VFIterator VFi(pos.V(1)->VFp(),pos.V(1)->VFi()); while (!VFi.End()) { for (int j=0;j<3;j++) { PosType p; p.Set(VFi.f,VFi.z,VFi.f->V(VFi.z)); h_ret.push_back(HeapElem(new TriEdgeCollapse(p,_Imark()))); std::push_heap(h_ret.begin(),h_ret.end()); //// update the mark of the vertices VFi.f->V(VFi.z)->IMark() = _Imark(); VFi.f->V( (VFi.z+1) % 3 )->IMark() = _Imark(); } VFi++; } } ModifierType IsOfType(){ return TriEdgeCollapseOp;} bool IsFeasible(){ return (!pos.V(0)->IsS() // bruttino qui...non toccare i vertici selezionati (pro-ponchio) && _EC.LinkConditions(pos)); } bool IsUpToDate(){ VertexType *v0=pos.V(0); VertexType *v1=pos.V(1); if(! (( (!v0->IsD()) && (!v1->IsD())) && _Imark()>=v0->IMark() && _Imark()>=v1->IMark())) { FAIL::OFD(); return false; } else return true; } virtual ScalarType Priority(){ // return _priority; } virtual void Init(TriMeshType&m,LocalOptimization::HeapType&h_ret){ h_ret.clear(); TriMeshType::FaceIterator fi; int j; for(fi = m.face.begin(); fi != m.face.end();++fi) if(!(*fi).IsD()){ for (int j=0;j<3;j++) { PosType p=PosType(&*fi,j,(*fi).V(j)); h_ret.push_back(HeapElem(new TriEdgeCollapse(p,m.IMark()))); } } } }; }//end namespace tri }//end namespace vcg /// 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; ///// Return the priority to be used in the heap (implement static priority) //virtual ScalarType Priority()=0; ///// Compute the error caused by this modification (can be the same as priority) //virtual ScalarType ComputeError()=0; ///// Perform the operation and return the variation in the number of simplicies (>0 is refinement, <0 is simplification) //virtual int Execute()=0; ///// perform initialization //virtual void Init(MESH_TYPE&m,HeapType&)=0; ///// Update the heap as a consequence of this operation //virtual void UpdateHeap(HeapType&)=0; #endif