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 #ifndef _VCG_EDGE_TOPOLOGY
00025 #define _VCG_EDGE_TOPOLOGY
00026
00027 #include <vector>
00028 #include <algorithm>
00029 #include <vcg/simplex/edge/pos.h>
00030
00031 namespace vcg {
00032 namespace edge {
00034 template <class EdgeType>
00035 inline bool IsEdgeManifoldFF( EdgeType const & e, const int j )
00036 {
00037 assert(e.cFFp(j) != 0);
00038
00039 if(EdgeType::HasFFAdjacency())
00040 return ( e.cFFp(j) == &e || &e == e.cFFp(j)->cFFp(e.cFFi(j)) );
00041 else
00042 return true;
00043 }
00044
00049 template <class EdgeType>
00050 inline bool IsEdgeBorder(EdgeType const & e, const int j )
00051 {
00052 if(EdgeType::HasEEAdjacency())
00053 return e.cEEp(j)==&e;
00054
00055 assert(0);
00056 return true;
00057 }
00058
00059 template <class VertexType>
00060 void VVStarVE(VertexType* vp, std::vector<VertexType *> &starVec)
00061 {
00062 starVec.clear();
00063 edge::VEIterator<typename VertexType::EdgeType> vei(vp);
00064 while(!vei.End())
00065 {
00066 starVec.push_back(vei.V1());
00067 ++vei;
00068 }
00069 }
00070
00071 template <class EdgeType>
00072 void VEStarVE(const typename EdgeType::VertexType* vp, std::vector<EdgeType *> &starVec)
00073 {
00074 starVec.clear();
00075 edge::VEIterator<EdgeType> vei(vp);
00076 while(!vei.End())
00077 {
00078 starVec.push_back(vei.E());
00079 ++vei;
00080 }
00081 }
00082
00084 template <class EdgeType>
00085 void VEDetach(EdgeType & e)
00086 {
00087 VEDetach(e,0);
00088 VEDetach(e,1);
00089 }
00090
00093 template <class EdgeType>
00094 void VEDetach(EdgeType & e, int z)
00095 {
00096 typename EdgeType::VertexType *vz = e.V(z);
00097
00098 if(vz->VEp()==&e )
00099 {
00100 assert(vz->VEi() == z);
00101 vz->VEp() = e.VEp(z);
00102 vz->VEi() = e.VEi(z);
00103 return;
00104 }
00105 else
00106 {
00107 for( VEIterator<EdgeType> vei(vz);!vei.End();++vei)
00108 {
00109 if(vei.E()->VEp(vei.I()) == &e)
00110 {
00111 vei.e->VEp(vei.z) = e.VEp(z);
00112 vei.e->VEi(vei.z) = e.VEi(z);
00113 return;
00114 }
00115 }
00116 assert(0);
00117 }
00118 }
00119
00121 template <class EdgeType>
00122 void VEAppend(EdgeType* e, int z)
00123 {
00124 typename EdgeType::VertexType *v = e->V(z);
00125 if (v->VEp()!=0)
00126 {
00127 EdgeType *e0=v->VEp();
00128 int z0=v->VEi();
00129
00130 e->VEp(z)=e0;
00131 e->VEi(z)=z0;
00132 }
00133 else
00134 {
00135 e->VEp(z)=0;
00136 e->VEi(z)=-1;
00137 }
00138 v->VEp()=e;
00139 v->VEi()=z;
00140 }
00141
00142
00160 template <class MeshType>
00161 void VEEdgeCollapse(MeshType &poly, typename MeshType::EdgeType *e0, const int z)
00162 {
00163 typedef typename MeshType::EdgeType EdgeType;
00164 typedef typename MeshType::VertexType VertexType;
00165
00166 VertexType *vd = e0->V(z);
00167
00168 std::vector<EdgeType *> starVecEp;
00169 edge::VEStarVE(vd,starVecEp);
00170 if(starVecEp.size()!=2) return;
00171
00172 EdgeType *e1=0;
00173 if( starVecEp[0] == e0 ) e1 = starVecEp[1];
00174 if( starVecEp[1] == e0 ) e1 = starVecEp[0];
00175 assert(e1 && (e1!=e0) );
00176
00177
00178 int z1 = -1;
00179 if(e1->V(0) == vd) z1=1;
00180 if(e1->V(1) == vd) z1=0;
00181 assert(z1!=-1);
00182
00183 VertexType *v1 = e1->V(z1);
00184 assert(v1 != vd);
00185
00186 edge::VEDetach(*e1);
00187
00188 edge::VEDetach(*e0,z);
00189 e0->V(z) = v1;
00190 edge::VEAppend(e0, z);
00191
00192 tri::Allocator<MeshType>::DeleteEdge(poly,*e1);
00193 tri::Allocator<MeshType>::DeleteVertex(poly,*vd);
00194 }
00195
00196 template <class MeshType>
00197 void VEEdgeCollapse(MeshType &poly, typename MeshType::VertexType *v)
00198 {
00199 VEEdgeCollapse(poly,v->VEp(),v->VEi());
00200 }
00204 template <class MeshType>
00205 void VEEdgeSplit(MeshType &poly, typename MeshType::EdgeType *e, typename MeshType::VertexType &v)
00206 {
00207 typename MeshType::VertexPointer v1 = e->V(1);
00208 edge::VEDetach(*e,1);
00209 e->V(1) = &v;
00210 edge::VEAppend(e,1);
00211
00212 typename MeshType::EdgeIterator ei = tri::Allocator<MeshType>::AddEdges(poly, 1);
00213 ei->V(0)=&v;
00214 ei->V(1)=v1;
00215 edge::VEAppend(&*ei,0);
00216 edge::VEAppend(&*ei,1);
00217 }
00218
00219 template <class MeshType>
00220 typename MeshType::VertexPointer VEEdgeSplit(MeshType &poly, typename MeshType::EdgeType *e, const typename MeshType::CoordType &p)
00221 {
00222 typename MeshType::VertexIterator vi = tri::Allocator<MeshType>::AddVertex(poly,p);
00223 VEEdgeSplit(poly,e,*vi);
00224 return &*vi;
00225 }
00226
00227 template <class MeshType>
00228 typename MeshType::VertexPointer VEEdgeSplit(MeshType &poly, typename MeshType::EdgeType *e, const typename MeshType::CoordType &p, const typename MeshType::CoordType &n)
00229 {
00230 typename MeshType::VertexIterator vi = tri::Allocator<MeshType>::AddVertex(poly,p,n);
00231 VEEdgeSplit(poly,e,*vi);
00232 return &*vi;
00233 }
00234
00235
00241 template <class EdgeType>
00242 int VEDegree(const typename EdgeType::VertexType* vp)
00243 {
00244 int cnt=0;
00245 edge::VEIterator<EdgeType> vei(vp);
00246 while(!vei.End())
00247 {
00248 ++cnt;
00249 ++vei;
00250 }
00251 return cnt;
00252 }
00253
00254
00255 }
00256 }
00257
00258
00259 #endif