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_FACE_TOPOLOGY
00025 #define _VCG_FACE_TOPOLOGY
00026
00027 #include <vcg/simplex/face/pos.h>
00028 #include <set>
00029
00030 namespace vcg {
00031 namespace face {
00034
00039 template <class FaceType>
00040 inline bool IsManifold( FaceType const & f, const int j )
00041 {
00042 assert(f.cFFp(j) != 0);
00043 if(FaceType::HasFFAdjacency())
00044 return ( f.cFFp(j) == &f || &f == f.cFFp(j)->cFFp(f.cFFi(j)) );
00045 else
00046 return true;
00047 }
00048
00053 template <class FaceType>
00054 inline bool IsBorder(FaceType const & f, const int j )
00055 {
00056 if(FaceType::HasFFAdjacency())
00057 return f.cFFp(j)==&f;
00058
00059
00060 assert(0);
00061 return true;
00062 }
00063
00082 template <class FaceType>
00083 inline typename FaceType::ScalarType DihedralAngleRad(FaceType & f, const int i )
00084 {
00085 typedef typename FaceType::ScalarType ScalarType;
00086 typedef typename FaceType::CoordType CoordType;
00087 typedef typename FaceType::VertexType VertexType;
00088
00089 FaceType *f0 = &f;
00090 FaceType *f1 = f.FFp(i);
00091 int i0=i;
00092 int i1=f.FFi(i);
00093 VertexType *vf0 = f0->V2(i0);
00094 VertexType *vf1 = f1->V2(i1);
00095
00096 CoordType n0 = TriangleNormal(*f0).Normalize();
00097 CoordType n1 = TriangleNormal(*f1).Normalize();
00098 ScalarType off0 = n0*vf0->P();
00099 ScalarType off1 = n1*vf1->P();
00100
00101 ScalarType dist01 = off0 - n0*vf1->P();
00102 ScalarType dist10 = off1 - n1*vf0->P();
00103
00104
00105 ScalarType sign;
00106 if(fabs(dist01) > fabs(dist10)) sign = dist01;
00107 else sign=dist10;
00108
00109 ScalarType angleRad=AngleN(n0,n1);
00110
00111 if(sign > 0 ) return angleRad;
00112 else return -angleRad;
00113 }
00114
00116 template <class FaceType>
00117 inline int BorderCount(FaceType const & f)
00118 {
00119 if(FaceType::HasFFAdjacency())
00120 {
00121 int t = 0;
00122 if( IsBorder(f,0) ) ++t;
00123 if( IsBorder(f,1) ) ++t;
00124 if( IsBorder(f,2) ) ++t;
00125 return t;
00126 }
00127 else return 3;
00128 }
00129
00130
00132 template <class FaceType>
00133 inline int ComplexSize(FaceType & f, const int e)
00134 {
00135 if(FaceType::HasFFAdjacency())
00136 {
00137 if(face::IsBorder<FaceType>(f,e)) return 1;
00138 if(face::IsManifold<FaceType>(f,e)) return 2;
00139
00140
00141 Pos< FaceType > fpos(&f,e);
00142 int cnt=0;
00143 do
00144 {
00145 fpos.NextF();
00146 assert(!fpos.IsBorder());
00147 assert(!fpos.IsManifold());
00148 ++cnt;
00149 }
00150 while(fpos.f!=&f);
00151 assert (cnt>2);
00152 return cnt;
00153 }
00154 assert(0);
00155 return 2;
00156 }
00157
00158
00165 template <class FaceType>
00166 bool FFCorrectness(FaceType & f, const int e)
00167 {
00168 if(f.FFp(e)==0) return false;
00169
00170 if(f.FFp(e)==&f)
00171 {
00172 if(f.FFi(e)==e) return true;
00173 else return false;
00174 }
00175
00176 if(f.FFp(e)->FFp(f.FFi(e))==&f)
00177 {
00178 if(f.FFp(e)->FFi(f.FFi(e))==e) return true;
00179 else return false;
00180 }
00181
00182
00183
00184
00185 Pos< FaceType > curFace(&f,e);
00186 int cnt=0;
00187 do
00188 {
00189 if(curFace.IsManifold()) return false;
00190 if(curFace.IsBorder()) return false;
00191 curFace.NextF();
00192 cnt++;
00193 assert(cnt<100);
00194 }
00195 while ( curFace.f != &f);
00196 return true;
00197 }
00198
00199
00207 template <class FaceType>
00208 void FFDetachManifold(FaceType & f, const int e)
00209 {
00210 assert(FFCorrectness<FaceType>(f,e));
00211 assert(!IsBorder<FaceType>(f,e));
00212 FaceType *ffp = f.FFp(e);
00213
00214 int ffi=f.FFi(e);
00215
00216 f.FFp(e)=&f;
00217 f.FFi(e)=e;
00218 ffp->FFp(ffi)=ffp;
00219 ffp->FFi(ffi)=ffi;
00220
00221 f.SetB(e);
00222 f.ClearF(e);
00223 ffp->SetB(ffi);
00224 ffp->ClearF(ffi);
00225
00226 assert(FFCorrectness<FaceType>(f,e));
00227 assert(FFCorrectness<FaceType>(*ffp,ffi));
00228 }
00229
00237 template <class FaceType>
00238 void FFDetach(FaceType & f, const int e)
00239 {
00240 assert(FFCorrectness<FaceType>(f,e));
00241 assert(!IsBorder<FaceType>(f,e));
00242 int complexity=ComplexSize(f,e);
00243 (void) complexity;
00244 assert(complexity>0);
00245
00246 Pos< FaceType > FirstFace(&f,e);
00247 Pos< FaceType > LastFace(&f,e);
00248 FirstFace.NextF();
00249 LastFace.NextF();
00250 int cnt=0;
00251
00252
00253
00254
00255
00256 while ( LastFace.f->FFp(LastFace.z) != &f)
00257 {
00258 assert(ComplexSize(*LastFace.f,LastFace.z)==complexity);
00259 assert(!LastFace.IsManifold());
00260 assert(!LastFace.IsBorder());
00261 LastFace.NextF();
00262 cnt++;
00263 assert(cnt<100);
00264 }
00265
00266 assert(LastFace.f->FFp(LastFace.z)==&f);
00267 assert(f.FFp(e)== FirstFace.f);
00268
00269
00270 LastFace.f->FFp(LastFace.z) = FirstFace.f;
00271 LastFace.f->FFi(LastFace.z) = FirstFace.z;
00272 assert(ComplexSize(*LastFace.f,LastFace.z)==complexity-1);
00273
00274
00275 f.FFp(e) = &f;
00276 f.FFi(e) = e;
00277 assert(ComplexSize(f,e)==1);
00278
00279 assert(FFCorrectness<FaceType>(*LastFace.f,LastFace.z));
00280 assert(FFCorrectness<FaceType>(f,e));
00281 }
00282
00283
00290 template <class FaceType>
00291 void FFAttach(FaceType * &f, int z1, FaceType *&f2, int z2)
00292 {
00293
00294 Pos< FaceType > EPB(f2,z2);
00295 Pos< FaceType > TEPB;
00296 TEPB = EPB;
00297 EPB.NextF();
00298 while( EPB.f != f2)
00299 {
00300 TEPB = EPB;
00301 EPB.NextF();
00302 }
00303
00304 FaceType *f1prec = f->FFp(z1);
00305 int z1prec = f->FFi(z1);
00306
00307 f->FFp(z1) = TEPB.f->FFp(TEPB.z);
00308 f->FFi(z1) = TEPB.f->FFi(TEPB.z);
00309
00310 TEPB.f->FFp(TEPB.z) = f1prec;
00311 TEPB.f->FFi(TEPB.z) = z1prec;
00312 }
00313
00321 template <class FaceType>
00322 void FFAttachManifold(FaceType * &f1, int z1, FaceType *&f2, int z2)
00323 {
00324 assert(IsBorder<FaceType>(*f1,z1));
00325 assert(IsBorder<FaceType>(*f2,z2));
00326 assert(f1->V0(z1) == f2->V0(z2) || f1->V0(z1) == f2->V1(z2));
00327 assert(f1->V1(z1) == f2->V0(z2) || f1->V1(z1) == f2->V1(z2));
00328 f1->FFp(z1) = f2;
00329 f1->FFi(z1) = z2;
00330 f2->FFp(z2) = f1;
00331 f2->FFi(z2) = z1;
00332 }
00333
00334
00335 template <class FaceType>
00336 void FFSetBorder(FaceType * &f1, int z1)
00337 {
00338 assert(f1->FFp(z1)==0 || IsBorder(*f1,z1));
00339
00340 f1->FFp(z1)=f1;
00341 f1->FFi(z1)=z1;
00342 }
00343
00344 template <class FaceType>
00345 void AssertAdj(FaceType & f)
00346 {
00347 (void)f;
00348 assert(f.FFp(0)->FFp(f.FFi(0))==&f);
00349 assert(f.FFp(1)->FFp(f.FFi(1))==&f);
00350 assert(f.FFp(2)->FFp(f.FFi(2))==&f);
00351
00352 assert(f.FFp(0)->FFi(f.FFi(0))==0);
00353 assert(f.FFp(1)->FFi(f.FFi(1))==1);
00354 assert(f.FFp(2)->FFi(f.FFi(2))==2);
00355 }
00356
00362 template <class FaceType>
00363 bool CheckOrientation(FaceType &f, int z)
00364 {
00365
00366 FaceType *original = f.FFp(z);
00367 double nf2,ng2;
00368 nf2=f.N()[2];
00369 ng2=original->N()[2];
00370
00371 if (IsBorder(f, z))
00372 return true;
00373 else
00374 {
00375 FaceType *g = f.FFp(z);
00376 int gi = f.FFi(z);
00377
00378 if (nf2/abs(nf2)==ng2/abs(ng2))
00379 return true;
00380 else
00381 return false;
00382 }
00383 }
00384
00385
00390 template <class FaceType>
00391 void SwapEdge(FaceType &f, const int z) { SwapEdge<FaceType,true>(f,z); }
00392
00393 template <class FaceType, bool UpdateTopology>
00394 void SwapEdge(FaceType &f, const int z)
00395 {
00396
00397 std::swap(f.V0(z), f.V1(z));
00398
00399
00400 bool Faux1 = f.IsF((z+1)%3);
00401 bool Faux2 = f.IsF((z+2)%3);
00402 if(Faux1) f.SetF((z+2)%3); else f.ClearF((z+2)%3);
00403 if(Faux2) f.SetF((z+1)%3); else f.ClearF((z+1)%3);
00404
00405 if(f.HasFFAdjacency() && UpdateTopology)
00406 {
00407
00408 int z1 = (z+1)%3;
00409 int z2 = (z+2)%3;
00410 FaceType *g1p = f.FFp(z1);
00411 FaceType *g2p = f.FFp(z2);
00412 int g1i = f.FFi(z1);
00413 int g2i = f.FFi(z2);
00414
00415
00416
00417 if (g1p != &f)
00418 {
00419 g1p->FFi(g1i) = z2;
00420 f.FFi(z2) = g1i;
00421 }
00422 else
00423 {
00424 f.FFi(z2) = z2;
00425 }
00426
00427 if (g2p != &f)
00428 {
00429 g2p->FFi(g2i) = z1;
00430 f.FFi(z1) = g2i;
00431 }
00432 else
00433 {
00434 f.FFi(z1) = z1;
00435 }
00436
00437
00438 f.FFp(z1) = g2p;
00439 f.FFp(z2) = g1p;
00440 }
00441 }
00442
00447 template <class FaceType>
00448 bool FFLinkCondition(FaceType &f, const int z)
00449 {
00450 typedef typename FaceType::VertexType VertexType;
00451 typedef typename vcg::face::Pos< FaceType > PosType;
00452
00453 VertexType *v0=f.V0(z);
00454 VertexType *v1=f.V1(z);
00455
00456 PosType p0(&f,v0);
00457 PosType p1(&f,v1);
00458 std::vector<VertexType *>v0Vec;
00459 std::vector<VertexType *>v1Vec;
00460 VVOrderedStarFF(p0,v0Vec);
00461 VVOrderedStarFF(p1,v1Vec);
00462 std::set<VertexType *> v0set;
00463 v0set.insert(v0Vec.begin(),v0Vec.end());
00464 assert(v0set.size() == v0Vec.size());
00465 int cnt =0;
00466 for(size_t i=0;i<v1Vec.size();++i)
00467 if(v0set.find(v1Vec[i]) != v0set.end())
00468 cnt++;
00469
00470 if(face::IsBorder(f,z) && (cnt==1)) return true;
00471 if(!face::IsBorder(f,z) && (cnt==2)) return true;
00472
00473 return false;
00474 }
00475
00492 template <class MeshType>
00493 void FFEdgeCollapse(MeshType &m, typename MeshType::FaceType &f, const int z)
00494 {
00495 typedef typename MeshType::FaceType FaceType;
00496 typedef typename MeshType::VertexType VertexType;
00497 typedef typename vcg::face::Pos< FaceType > PosType;
00498 FaceType *f0 = &f;
00499 int z0=z;
00500 FaceType *f1 = f.FFp(z);
00501 int z1=f.FFi(z);
00502
00503 VertexType *delV=f.V0(z);
00504 VertexType *surV=f.V1(z);
00505
00506
00507 PosType delPos(f0,delV);
00508 std::vector<PosType> faceToBeChanged;
00509 VFOrderedStarFF(delPos,faceToBeChanged);
00510
00511
00512 FaceType *f01= 0,*f02= 0,*f11= 0,*f12= 0;
00513 int i01=-1, i02=-1, i11=-1, i12=-1;
00514
00515 bool f0Faux = f0->IsF((z0+1)%3) && f0->IsF((z0+2)%3);
00516 bool f1Faux = f1->IsF((z1+1)%3) && f1->IsF((z1+2)%3);
00517
00518 if(!face::IsBorder(*f0,(z0+1)%3)) { f01 = f0->FFp((z0+1)%3); i01=f0->FFi((z0+1)%3); FFDetachManifold(*f0,(z0+1)%3);}
00519 if(!face::IsBorder(*f0,(z0+2)%3)) { f02 = f0->FFp((z0+2)%3); i02=f0->FFi((z0+2)%3); FFDetachManifold(*f0,(z0+2)%3);}
00520 if(!face::IsBorder(*f1,(z1+1)%3)) { f11 = f1->FFp((z1+1)%3); i11=f1->FFi((z1+1)%3); FFDetachManifold(*f1,(z1+1)%3);}
00521 if(!face::IsBorder(*f1,(z1+2)%3)) { f12 = f1->FFp((z1+2)%3); i12=f1->FFi((z1+2)%3); FFDetachManifold(*f1,(z1+2)%3);}
00522
00523
00524 for(size_t i=0;i<faceToBeChanged.size();++i) {
00525 assert(faceToBeChanged[i].V() == delV);
00526 faceToBeChanged[i].F()->V(faceToBeChanged[i].VInd()) =surV;
00527 }
00528
00529 if(f01 && f02)
00530 {
00531 FFAttachManifold(f01,i01,f02,i02);
00532 if(f0Faux) {f01->SetF(i01); f02->SetF(i02);}
00533 }
00534 if(f11 && f12) {
00535 FFAttachManifold(f11,i11,f12,i12);
00536 if(f1Faux) {f11->SetF(i11); f12->SetF(i12);}
00537 }
00538 tri::Allocator<MeshType>::DeleteFace(m,*f0);
00539 if(f1!=f0) tri::Allocator<MeshType>::DeleteFace(m,*f1);
00540 tri::Allocator<MeshType>::DeleteVertex(m,*delV);
00541 }
00542
00562 template <class FaceType>
00563 bool CheckFlipEdgeNormal(FaceType &f, const int z, const float angleRad)
00564 {
00565 typedef typename FaceType::VertexType VertexType;
00566 typedef typename VertexType::CoordType CoordType;
00567
00568 VertexType *OldDiag0 = f.V0(z);
00569 VertexType *OldDiag1 = f.V1(z);
00570
00571 VertexType *NewDiag0 = f.V2(z);
00572 VertexType *NewDiag1 = f.FFp(z)->V2(f.FFi(z));
00573
00574 assert((NewDiag1 != NewDiag0) && (NewDiag1 != OldDiag0) && (NewDiag1 != OldDiag1));
00575
00576 CoordType oldN0 = NormalizedNormal( NewDiag0->cP(),OldDiag0->cP(),OldDiag1->cP());
00577 CoordType oldN1 = NormalizedNormal( NewDiag1->cP(),OldDiag1->cP(),OldDiag0->cP());
00578 CoordType newN0 = NormalizedNormal( OldDiag0->cP(),NewDiag1->cP(),NewDiag0->cP());
00579 CoordType newN1 = NormalizedNormal( OldDiag1->cP(),NewDiag0->cP(),NewDiag1->cP());
00580 if(AngleN(oldN0,newN0) > angleRad) return false;
00581 if(AngleN(oldN0,newN1) > angleRad) return false;
00582 if(AngleN(oldN1,newN0) > angleRad) return false;
00583 if(AngleN(oldN1,newN1) > angleRad) return false;
00584
00585 return true;
00586 }
00587
00594 template <class FaceType>
00595 bool CheckFlipEdge(FaceType &f, int z)
00596 {
00597 typedef typename FaceType::VertexType VertexType;
00598 typedef typename vcg::face::Pos< FaceType > PosType;
00599
00600 if (z<0 || z>2) return false;
00601
00602
00603 if (face::IsBorder(f, z)) return false;
00604
00605 FaceType *g = f.FFp(z);
00606 int w = f.FFi(z);
00607
00608
00609
00610 if (g->V(w)!=f.V1(z) || g->V1(w)!=f.V(z) )
00611 return false;
00612
00613
00614
00615 VertexType *f_v2 = f.V2(z);
00616 VertexType *g_v2 = g->V2(w);
00617
00618
00619 if (f_v2 == g_v2) return false;
00620
00621
00622
00623
00624 PosType pos(&f, (z+2)%3, f_v2);
00625 PosType startPos=pos;
00626 do
00627 {
00628 pos.NextE();
00629 if (g_v2 == pos.VFlip())
00630 return false;
00631 }
00632 while (pos != startPos);
00633
00634 return true;
00635 }
00636
00646 template <class FaceType>
00647 void FlipEdge(FaceType &f, const int z)
00648 {
00649 assert(z>=0);
00650 assert(z<3);
00651 assert( !IsBorder(f,z) );
00652 assert( face::IsManifold<FaceType>(f, z));
00653
00654 FaceType *g = f.FFp(z);
00655 int w = f.FFi(z);
00656
00657 assert( g->V(w) == f.V1(z) );
00658 assert( g->V1(w)== f.V(z) );
00659 assert( g->V2(w)!= f.V(z) );
00660 assert( g->V2(w)!= f.V1(z) );
00661 assert( g->V2(w)!= f.V2(z) );
00662
00663 f.V1(z) = g->V2(w);
00664 g->V1(w) = f.V2(z);
00665
00666 f.FFp(z) = g->FFp((w+1)%3);
00667 f.FFi(z) = g->FFi((w+1)%3);
00668 g->FFp(w) = f.FFp((z+1)%3);
00669 g->FFi(w) = f.FFi((z+1)%3);
00670 f.FFp((z+1)%3) = g;
00671 f.FFi((z+1)%3) = (w+1)%3;
00672 g->FFp((w+1)%3) = &f;
00673 g->FFi((w+1)%3) = (z+1)%3;
00674
00675 if(f.FFp(z)==g)
00676 {
00677 f.FFp(z) = &f;
00678 f.FFi(z) = z;
00679 }
00680 else
00681 {
00682 f.FFp(z)->FFp( f.FFi(z) ) = &f;
00683 f.FFp(z)->FFi( f.FFi(z) ) = z;
00684 }
00685 if(g->FFp(w)==&f)
00686 {
00687 g->FFp(w)=g;
00688 g->FFi(w)=w;
00689 }
00690 else
00691 {
00692 g->FFp(w)->FFp( g->FFi(w) ) = g;
00693 g->FFp(w)->FFi( g->FFi(w) ) = w;
00694 }
00695 }
00696
00697 template <class FaceType>
00698 void VFDetach(FaceType & f)
00699 {
00700 VFDetach(f,0);
00701 VFDetach(f,1);
00702 VFDetach(f,2);
00703 }
00704
00705
00706
00707
00708 template <class FaceType>
00709 void VFDetach(FaceType & f, int z)
00710 {
00711 if(f.V(z)->VFp()==&f )
00712 {
00713 int fz = f.V(z)->VFi();
00714 f.V(z)->VFp() = f.VFp(fz);
00715 f.V(z)->VFi() = f.VFi(fz);
00716 }
00717 else
00718 {
00719 VFIterator<FaceType> x(f.V(z)->VFp(),f.V(z)->VFi());
00720 VFIterator<FaceType> y;
00721
00722 for(;;)
00723 {
00724 y = x;
00725 ++x;
00726 assert(x.f!=0);
00727 if(x.f==&f)
00728 {
00729 y.f->VFp(y.z) = f.VFp(z);
00730 y.f->VFi(y.z) = f.VFi(z);
00731 break;
00732 }
00733 }
00734 }
00735 }
00736
00738 template <class FaceType>
00739 void VFAppend(FaceType* & f, int z)
00740 {
00741 typename FaceType::VertexType *v = f->V(z);
00742 if (v->VFp()!=0)
00743 {
00744 FaceType *f0=v->VFp();
00745 int z0=v->VFi();
00746
00747 f->VFp(z)=f0;
00748 f->VFi(z)=z0;
00749 }
00750 v->VFp()=f;
00751 v->VFi()=z;
00752 }
00753
00762 template <class FaceType>
00763 void VVStarVF( typename FaceType::VertexType* vp, std::vector<typename FaceType::VertexType *> &starVec)
00764 {
00765 typedef typename FaceType::VertexType* VertexPointer;
00766 starVec.clear();
00767 face::VFIterator<FaceType> vfi(vp);
00768 while(!vfi.End())
00769 {
00770 starVec.push_back(vfi.F()->V1(vfi.I()));
00771 starVec.push_back(vfi.F()->V2(vfi.I()));
00772 ++vfi;
00773 }
00774
00775 std::sort(starVec.begin(),starVec.end());
00776 typename std::vector<VertexPointer>::iterator new_end = std::unique(starVec.begin(),starVec.end());
00777 starVec.resize(new_end-starVec.begin());
00778 }
00779
00788 template <class FaceType>
00789 void VVExtendedStarVF(typename FaceType::VertexType* vp,
00790 const int num_step,
00791 std::vector<typename FaceType::VertexType *> &vertVec)
00792 {
00793 typedef typename FaceType::VertexType VertexType;
00795 vertVec.clear();
00796 vcg::face::VVStarVF<FaceType>(vp,vertVec);
00799 for (int step=0;step<num_step-1;step++)
00800 {
00801 std::vector<VertexType *> toAdd;
00802 for (unsigned int i=0;i<vertVec.size();i++)
00803 {
00804 std::vector<VertexType *> Vtemp;
00805 vcg::face::VVStarVF<FaceType>(vertVec[i],Vtemp);
00806 toAdd.insert(toAdd.end(),Vtemp.begin(),Vtemp.end());
00807 }
00808 vertVec.insert(vertVec.end(),toAdd.begin(),toAdd.end());
00809 std::sort(vertVec.begin(),vertVec.end());
00810 typename std::vector<typename FaceType::VertexType *>::iterator new_end=std::unique(vertVec.begin(),vertVec.end());
00811 int dist=distance(vertVec.begin(),new_end);
00812 vertVec.resize(dist);
00813 }
00814 }
00815
00823 template <class FaceType>
00824 void VFStarVF( typename FaceType::VertexType* vp,
00825 std::vector<FaceType *> &faceVec,
00826 std::vector<int> &indexes)
00827 {
00828 faceVec.clear();
00829 indexes.clear();
00830 face::VFIterator<FaceType> vfi(vp);
00831 while(!vfi.End())
00832 {
00833 faceVec.push_back(vfi.F());
00834 indexes.push_back(vfi.I());
00835 ++vfi;
00836 }
00837 }
00838
00839
00848 template <class FaceType>
00849 void EFStarFF( FaceType* fp, int ei,
00850 std::vector<FaceType *> &faceVec,
00851 std::vector<int> &indVed)
00852 {
00853 assert(fp->FFp(ei)!=0);
00854 faceVec.clear();
00855 indVed.clear();
00856 FaceType* fpit=fp;
00857 int eit=ei;
00858 do
00859 {
00860 faceVec.push_back(fpit);
00861 indVed.push_back(eit);
00862 FaceType *new_fpit = fpit->FFp(eit);
00863 int new_eit = fpit->FFi(eit);
00864 fpit=new_fpit;
00865 eit=new_eit;
00866 } while(fpit != fp);
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876 template <class FaceType>
00877 static void FFExtendedStarFF(FaceType *fp,
00878 const int num_step,
00879 std::vector<FaceType*> &faceVec)
00880 {
00882 faceVec.push_back(fp);
00885 for (int step=0;step<num_step;step++)
00886 {
00887 std::vector<FaceType*> toAdd;
00888 for (unsigned int i=0;i<faceVec.size();i++)
00889 {
00890 FaceType *f=faceVec[i];
00891 for (int k=0;k<3;k++)
00892 {
00893 FaceType *f1=f->FFp(k);
00894 if (f1==f)continue;
00895 toAdd.push_back(f1);
00896 }
00897 }
00898 faceVec.insert(faceVec.end(),toAdd.begin(),toAdd.end());
00899 std::sort(faceVec.begin(),faceVec.end());
00900 typename std::vector<FaceType*>::iterator new_end=std::unique(faceVec.begin(),faceVec.end());
00901 int dist=distance(faceVec.begin(),new_end);
00902 faceVec.resize(dist);
00903 }
00904 }
00905
00914 template <class FaceType>
00915 void VFExtendedStarVF(typename FaceType::VertexType* vp,
00916 const int num_step,
00917 std::vector<FaceType*> &faceVec)
00918 {
00920 faceVec.clear();
00921 std::vector<int> indexes;
00922 vcg::face::VFStarVF<FaceType>(vp,faceVec,indexes);
00925 for (int step=0;step<num_step;step++)
00926 {
00927 std::vector<FaceType*> toAdd;
00928 for (unsigned int i=0;i<faceVec.size();i++)
00929 {
00930 FaceType *f=faceVec[i];
00931 for (int k=0;k<3;k++)
00932 {
00933 FaceType *f1=f->FFp(k);
00934 if (f1==f)continue;
00935 toAdd.push_back(f1);
00936 }
00937 }
00938 faceVec.insert(faceVec.end(),toAdd.begin(),toAdd.end());
00939 std::sort(faceVec.begin(),faceVec.end());
00940 typename std::vector<FaceType*>::iterator new_end=std::unique(faceVec.begin(),faceVec.end());
00941 int dist=distance(faceVec.begin(),new_end);
00942 faceVec.resize(dist);
00943 }
00944 }
00945
00953 template <class FaceType>
00954 void VVOrderedStarFF(Pos<FaceType> &startPos,
00955 std::vector<typename FaceType::VertexType *> &vertexVec)
00956 {
00957 vertexVec.clear();
00958 std::vector<Pos<FaceType> > posVec;
00959 VFOrderedStarFF(startPos,posVec);
00960 for(size_t i=0;i<posVec.size();++i)
00961 vertexVec.push_back(posVec[i].VFlip());
00962 }
00963
00971 template <class FaceType>
00972 void VFOrderedStarFF(const Pos<FaceType> &startPos,
00973 std::vector<Pos<FaceType> > &posVec)
00974 {
00975 posVec.clear();
00976 bool foundBorder=false;
00977 size_t firstBorderInd;
00978 Pos<FaceType> curPos=startPos;
00979 do
00980 {
00981 assert(curPos.IsManifold());
00982 if(curPos.IsBorder() && !foundBorder) {
00983 foundBorder=true;
00984 firstBorderInd = posVec.size();
00985 }
00986 posVec.push_back(curPos);
00987 curPos.FlipF();
00988 curPos.FlipE();
00989 } while(curPos!=startPos);
00990
00991
00992 if(foundBorder)
00993 {
00994 size_t halfSize=posVec.size()/2;
00995 assert((posVec.size()%2)==0);
00996 posVec.erase(posVec.begin()+firstBorderInd+1+halfSize, posVec.end());
00997 posVec.erase(posVec.begin(),posVec.begin()+firstBorderInd+1);
00998 assert(posVec.size()==halfSize);
00999 }
01000 }
01001
01011 template <class FaceType>
01012 void VFOrderedStarFF(const Pos<FaceType> &startPos,
01013 std::vector<FaceType*> &faceVec,
01014 std::vector<int> &edgeVec)
01015 {
01016 std::vector<Pos<FaceType> > posVec;
01017 VFOrderedStarFF(startPos,posVec);
01018 faceVec.clear();
01019 edgeVec.clear();
01020 for(size_t i=0;i<posVec.size();++i)
01021 {
01022 faceVec.push_back(posVec[i].F());
01023 edgeVec.push_back(posVec[i].E());
01024 }
01025 }
01026
01033 template <class FaceType>
01034 bool ShareEdgeFF(FaceType *f0,FaceType *f1, int *i0=0, int *i1=0)
01035 {
01036 assert((!f0->IsD())&&(!f1->IsD()));
01037 for (int i=0;i<3;i++)
01038 if (f0->FFp(i)==f1)
01039 {
01040 if((i0!=0) && (i1!=0)) {
01041 *i0=i;
01042 *i1=f0->FFi(i);
01043 }
01044 return true;
01045 }
01046 return false;
01047 }
01048
01054 template <class FaceType>
01055 int CountSharedVertex(FaceType *f0,FaceType *f1)
01056 {
01057 int sharedCnt=0;
01058 for (int i=0;i<3;i++)
01059 for (int j=0;j<3;j++)
01060 if (f0->V(i)==f1->V(j)) {
01061 sharedCnt++;
01062 }
01063 return sharedCnt;
01064 }
01065
01072 template <class FaceType>
01073 bool FindSharedVertex(FaceType *f0,FaceType *f1, int &i, int &j)
01074 {
01075 for (i=0;i<3;i++)
01076 for (j=0;j<3;j++)
01077 if (f0->V(i)==f1->V(j)) return true;
01078
01079 i=-1;j=-1;
01080 return false;
01081 }
01082
01089 template <class FaceType>
01090 bool FindSharedEdge(FaceType *f0,FaceType *f1, int &i, int &j)
01091 {
01092 for (i=0;i<3;i++)
01093 for (j=0;j<3;j++)
01094 if( ( f0->V0(i)==f1->V0(j) || f0->V0(i)==f1->V1(j) ) &&
01095 ( f0->V1(i)==f1->V0(j) || f0->V1(i)==f1->V1(j) ) )
01096 return true;
01097 i=-1;j=-1;
01098 return false;
01099 }
01100
01107 template <class FaceType>
01108 bool FindSharedFaces(typename FaceType::VertexType *v0,
01109 typename FaceType::VertexType *v1,
01110 FaceType *&f0,
01111 FaceType *&f1,
01112 int &e0,
01113 int &e1)
01114 {
01115 std::vector<FaceType*> faces0;
01116 std::vector<FaceType*> faces1;
01117 std::vector<int> index0;
01118 std::vector<int> index1;
01119 VFStarVF<FaceType>(v0,faces0,index0);
01120 VFStarVF<FaceType>(v1,faces1,index1);
01122 std::sort(faces0.begin(),faces0.end());
01123 std::sort(faces1.begin(),faces1.end());
01124 std::vector<FaceType*> Intersection;
01125 std::set_intersection(faces0.begin(),faces0.end(),faces1.begin(),faces1.end(),std::back_inserter(Intersection));
01126 if (Intersection.size()<2)return false;
01127 assert(Intersection.size()==2);
01128 f0=Intersection[0];
01129 f1=Intersection[1];
01130 FindSharedEdge(f0,f1,e0,e1);
01132 if (f0->V(e0)!=v0)
01133 {
01134 std::swap(f0,f1);
01135 std::swap(e0,e1);
01136 }
01137 return true;
01138 }
01139
01141 }
01142 }
01143
01144 #endif
01145