Go to the documentation of this file.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 #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
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
00132
00133
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
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
00151
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
00177
00178
00179
00180
00181
00182
00183
00184
00185 ++vfi;
00186 }
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
00227 }
00228 }
00229 }
00230
00231 };
00232 }
00233 }
00234
00235 #endif