topology.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 #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); // never try to use this on uncomputed topology
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     //return f.IsBorder(j);
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   // just to be sure use the sign of the largest in absolute value;
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     // Non manifold case
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;   // Not computed or inconsistent topology
00169 
00170   if(f.FFp(e)==&f) // Border
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) // plain two manifold
00177   {
00178     if(f.FFp(e)->FFi(f.FFi(e))==e) return true;
00179     else return false;
00180   }
00181 
00182   // Non Manifold Case
00183   // all the faces must be connected in a loop.
00184 
00185   Pos< FaceType > curFace(&f,e);  // Build the half edge
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));  // Never try to detach a border edge!
00212     FaceType *ffp = f.FFp(e);
00213     //int ffi=f.FFp(e);
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));  // Never try to detach a border edge!
00242     int complexity=ComplexSize(f,e);
00243     (void) complexity;
00244     assert(complexity>0);
00245 
00246     Pos< FaceType > FirstFace(&f,e);  // Build the half edge
00247     Pos< FaceType > LastFace(&f,e);  // Build the half edge
00248     FirstFace.NextF();
00249     LastFace.NextF();
00250     int cnt=0;
00251 
00252     // then in case of non manifold face continue to advance LastFace
00253     // until I find it become the one that
00254     // preceed the face I want to erase
00255 
00256     while ( LastFace.f->FFp(LastFace.z) != &f)
00257     {
00258         assert(ComplexSize(*LastFace.f,LastFace.z)==complexity);
00259         assert(!LastFace.IsManifold());   // We enter in this loop only if we are on a non manifold edge
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     // Now we link the last one to the first one, skipping the face to be detached;
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     // At the end selfconnect the chosen edge to make a border.
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     //typedef FEdgePosB< FACE_TYPE > ETYPE;
00294     Pos< FaceType > EPB(f2,z2);
00295     Pos< FaceType > TEPB;
00296     TEPB = EPB;
00297     EPB.NextF();
00298     while( EPB.f != f2)  //Alla fine del ciclo TEPB contiene la faccia che precede f2
00299     {
00300         TEPB = EPB;
00301         EPB.NextF();
00302     }
00303     //Salvo i dati di f1 prima di sovrascrivere
00304   FaceType *f1prec = f->FFp(z1);
00305   int z1prec = f->FFi(z1);
00306     //Aggiorno f1
00307     f->FFp(z1) = TEPB.f->FFp(TEPB.z);
00308     f->FFi(z1) = TEPB.f->FFi(TEPB.z);
00309     //Aggiorno la faccia che precede f2
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 // This one should be called only on uniitialized faces.
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     // Added next section to calculate the difference between normal z-directions
00366     FaceType *original = f.FFp(z);
00367     double nf2,ng2;
00368     nf2=f.N()[2];
00369     ng2=original->N()[2];
00370     // End of additional section
00371     if (IsBorder(f, z))
00372         return true;
00373     else
00374     {
00375         FaceType *g = f.FFp(z);
00376         int gi = f.FFi(z);
00377         // changed if statement from: if (f.V0(z) == g->V1(gi))
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     // swap V0(z) with V1(z)
00397     std::swap(f.V0(z), f.V1(z));
00398 
00399     // Managemnt of faux edge information (edge z is not affected)
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         // store information to preserve topology
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         // g0 face topology is not affected by the swap
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         // finalize swap
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   //assert(0);
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   // Collect faces that have to be updated
00507   PosType delPos(f0,delV);
00508   std::vector<PosType> faceToBeChanged;
00509   VFOrderedStarFF(delPos,faceToBeChanged);
00510 
00511   // Topology Stitching
00512   FaceType *f01= 0,*f02= 0,*f11= 0,*f12= 0;
00513   int       i01=-1, i02=-1, i11=-1, i12=-1;
00514   // Note that the faux bit is preserved only if both of the edges to be stiched are faux.
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   // Final Pass to update the vertex ptrs in all the involved faces
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     // boundary edges cannot be flipped
00603   if (face::IsBorder(f, z)) return false;
00604 
00605     FaceType *g = f.FFp(z);
00606     int          w = f.FFi(z);
00607 
00608     // check if the vertices of the edge are the same
00609   // e.g. the mesh has to be well oriented
00610     if (g->V(w)!=f.V1(z) || g->V1(w)!=f.V(z) )
00611         return false;
00612 
00613     // check if the flipped edge is already present in the mesh
00614   // f_v2 and g_v2 are the vertices of the new edge
00615   VertexType *f_v2 = f.V2(z);
00616     VertexType *g_v2 = g->V2(w);
00617 
00618   // just a sanity check. If this happens the mesh is not manifold.
00619   if (f_v2 == g_v2) return false;
00620 
00621   // Now walk around f_v2, one of the two vertexes of the new edge
00622   // and check that it does not already exists.
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 // Stacca la faccia corrente dalla catena di facce incidenti sul vertice z,
00706 // NOTA funziona SOLO per la topologia VF!!!
00707 // usata nelle classi di collapse
00708 template <class FaceType>
00709 void VFDetach(FaceType & f, int z)
00710 {
00711     if(f.V(z)->VFp()==&f )  //if it is the first face detach from the begin
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  // scan the list of faces in order to finde the current face f to be detached
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) // found!
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         //append
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     /* Compute the set of faces adjacent to a given face using FF adjacency.
00871     * The set is faces is extended of a given number of step
00872     *   \param fp       pointer to the face whose star has to be computed.
00873     *  \param num_step the number of step to extend the star
00874     *   \param faceVec a std::vector of Face pointer that is filled with the adjacent faces.
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   // if we found a border we visited each face exactly twice,
00991   // and we have to extract the border-to-border pos sequence
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);//otherwhise non manifoldess
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 }        // end namespace
01142 }        // end namespace
01143 
01144 #endif
01145 


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