tri_edge_collapse.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 
00025 #ifndef __VCG_DECIMATION_TRICOLLAPSE
00026 #define __VCG_DECIMATION_TRICOLLAPSE
00027 
00028 #include<vcg/complex/algorithms/edge_collapse.h>
00029 #include<vcg/simplex/face/pos.h>
00030 #include<vcg/complex/algorithms/local_optimization.h>
00031 #include<vcg/complex/algorithms/update/topology.h>
00032 
00033 namespace vcg{
00034 namespace tri{
00035 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 template<class TriMeshType, class VertexPair, class MYTYPE>
00046 class TriEdgeCollapse: public LocalOptimization<TriMeshType>::LocModType
00047 {
00048 public:
00050   class FailStat {
00051   public:
00052   static int &Volume()           {static int vol=0; return vol;}
00053   static int &LinkConditionFace(){static int lkf=0; return lkf;}
00054   static int &LinkConditionEdge(){static int lke=0; return lke;}
00055   static int &LinkConditionVert(){static int lkv=0; return lkv;}
00056   static int &OutOfDate()        {static int ofd=0; return ofd;}
00057   static int &Border()           {static int bor=0; return bor;}
00058   static void Init()
00059   {
00060    Volume()           =0;
00061    LinkConditionFace()=0;
00062    LinkConditionEdge()=0;
00063    LinkConditionVert()=0;
00064    OutOfDate()        =0;
00065    Border()           =0;
00066   }
00067 };
00068 protected:
00069   typedef       typename TriMeshType::FaceType FaceType;
00070   typedef       typename TriMeshType::FaceType::VertexType VertexType;
00071 //      typedef typename VertexType::EdgeType EdgeType;
00072   typedef       typename FaceType::VertexType::CoordType CoordType;
00073   typedef       typename TriMeshType::VertexType::ScalarType ScalarType;
00074   typedef typename LocalOptimization<TriMeshType>::HeapElem HeapElem;
00075   typedef typename LocalOptimization<TriMeshType>::HeapType HeapType;
00076 
00077   TriMeshType *mt;
00079   VertexPair pos;
00080 
00082   static int& GlobalMark(){ static int im=0; return im;}
00083 
00085   int localMark;
00086 
00088   ScalarType _priority;
00089 
00090   public:
00092   inline        TriEdgeCollapse()
00093       {}
00095    inline TriEdgeCollapse(const VertexPair &p, int mark, BaseParameterClass *pp)
00096       {
00097         localMark = mark;
00098         pos=p;
00099         _priority = ComputePriority(pp);
00100       }
00101 
00102     ~TriEdgeCollapse()
00103       {}
00104 
00105 private:
00106 
00107 
00108 public:
00109 
00110   inline ScalarType ComputePriority(BaseParameterClass *)
00111   {
00112     _priority = Distance(pos.V(0)->cP(),pos.V(1)->cP());
00113     return _priority;
00114   }
00115 
00116   virtual const char *Info(TriMeshType &m) {
00117     mt = &m;
00118     static char buf[60];
00119       sprintf(buf,"%i -> %i %g\n", int(pos.V(0)-&m.vert[0]), int(pos.V(1)-&m.vert[0]),-_priority);
00120    return buf;
00121   }
00122 
00123   inline void Execute(TriMeshType &m, BaseParameterClass *)
00124   {
00125     CoordType MidPoint=(pos.V(0)->P()+pos.V(1)->P())/2.0;
00126     EdgeCollapser<TriMeshType,VertexPair>::Do(m, pos, MidPoint);
00127   }
00128 
00129   static bool IsSymmetric(BaseParameterClass *) { return true;}
00130 
00131   // This function is called after an action to re-add in the heap elements whose priority could have been changed.
00132   // in the plain case we just put again in the heap all the edges around the vertex resulting from the previous collapse: v[1].
00133   // if the collapse is not symmetric you should add also backward edges (because v0->v1 collapse could be different from v1->v0)
00134 
00135   inline  void UpdateHeap(HeapType & h_ret, BaseParameterClass *pp)
00136   {
00137     GlobalMark()++;
00138     VertexType *v[2];
00139     v[0]= pos.V(0);v[1]=pos.V(1);
00140     v[1]->IMark() = GlobalMark();
00141 
00142     // First loop around the remaining vertex to unmark visited flags
00143     vcg::face::VFIterator<FaceType> vfi(v[1]);
00144     while (!vfi.End()){
00145       vfi.V1()->ClearV();
00146       vfi.V2()->ClearV();
00147       ++vfi;
00148     }
00149 
00150     // Second Loop: add all the outgoing edges around v[1]
00151     // for each face add the two edges outgoing from v[1] and not visited.
00152     vfi = face::VFIterator<FaceType>(v[1]);
00153     while (!vfi.End())
00154     {
00155       assert(!vfi.F()->IsD());
00156       if( !(vfi.V1()->IsV()) && (vfi.V1()->IsRW()))
00157       {
00158         vfi.V1()->SetV();
00159         h_ret.push_back(HeapElem(new MYTYPE(VertexPair( vfi.V(),vfi.V1() ),GlobalMark(),pp)));
00160         std::push_heap(h_ret.begin(),h_ret.end());
00161         if(! this->IsSymmetric(pp)){
00162           h_ret.push_back(HeapElem(new MYTYPE(VertexPair( vfi.V1(),vfi.V()),GlobalMark(),pp)));
00163           std::push_heap(h_ret.begin(),h_ret.end());
00164         }
00165       }
00166       if(  !(vfi.V2()->IsV()) && (vfi.V2()->IsRW()))
00167       {
00168         vfi.V2()->SetV();
00169         h_ret.push_back(HeapElem(new MYTYPE(VertexPair(vfi.F()->V(vfi.I()),vfi.F()->V2(vfi.I())),GlobalMark(),pp)));
00170         std::push_heap(h_ret.begin(),h_ret.end());
00171         if(! this->IsSymmetric(pp)){
00172           h_ret.push_back(HeapElem(new MYTYPE(VertexPair (vfi.F()->V1(vfi.I()),vfi.F()->V(vfi.I())),GlobalMark(),pp)));
00173           std::push_heap(h_ret.begin(),h_ret.end());
00174         }
00175       }
00176       //        if(vfi.V1()->IsRW() && vfi.V2()->IsRW() )
00177       //        {
00178       //          h_ret.push_back(HeapElem(new MYTYPE(EdgeType(vfi.V1(),vfi.V2()),this->GlobalMark())));
00179       //          std::push_heap(h_ret.begin(),h_ret.end());
00180       //          if(IsSymmetric()){
00181       //            h_ret.push_back(HeapElem(new MYTYPE(EdgeType(vfi.V2(),vfi.V1()), this->GlobalMark())));
00182       //            std::push_heap(h_ret.begin(),h_ret.end());
00183       //          }
00184       //        }
00185       ++vfi;
00186     } // end while
00187   }
00188 
00189   ModifierType IsOfType(){ return TriEdgeCollapseOp;}
00190 
00191   inline bool IsFeasible(BaseParameterClass *){
00192     return EdgeCollapser<TriMeshType,VertexPair>::LinkConditions(pos);
00193   }
00194 
00195   inline bool IsUpToDate() const
00196   {
00197       VertexType *v0=pos.cV(0);
00198       VertexType *v1=pos.cV(1);
00199       if( v0->IsD() || v1->IsD() ||
00200          localMark < v0->IMark()  ||
00201          localMark < v1->IMark()   )
00202       {
00203         ++FailStat::OutOfDate();
00204         return false;
00205       }
00206         return true;
00207   }
00208 
00209   virtual ScalarType Priority() const {
00210   return _priority;
00211   }
00212 
00213   static void Init(TriMeshType &m, HeapType &h_ret, BaseParameterClass *pp)
00214   {
00215     vcg::tri::RequirePerVertexMark(m);
00216     vcg::tri::UpdateTopology<TriMeshType>::VertexFace(m);
00217     h_ret.clear();
00218     typename TriMeshType::FaceIterator fi;
00219     for(fi = m.face.begin(); fi != m.face.end();++fi)
00220     if(!(*fi).IsD()){
00221        for (int j=0;j<3;j++)
00222       {
00223         VertexPair p((*fi).V0(j), (*fi).V1(j));
00224         p.Sort();
00225         h_ret.push_back(HeapElem(new MYTYPE(p, IMark(m),pp)));
00226         //printf("Inserting in heap coll %3i ->%3i %f\n",p.V()-&m.vert[0],p.VFlip()-&m.vert[0],h_ret.back().locModPtr->Priority());
00227       }
00228     }
00229   }
00230 
00231 };
00232 }//end namespace tri
00233 }//end namespace vcg
00234 
00235 #endif


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