pos.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 
00029 #ifndef __VCG_FACE_POS
00030 #define __VCG_FACE_POS
00031 
00032 #include <assert.h>
00033 
00034 namespace vcg {
00035 namespace face {
00036 
00039 
00040 // Needed Prototypes (pos is include before topology)
00041 template <class FaceType>
00042 bool IsBorder(FaceType const & f,  const int j );
00043 template <class FaceType>
00044 bool IsManifold(FaceType const & f,  const int j );
00045 
00054 template <class FaceType>
00055 class Pos
00056 {
00057 public:
00058 
00060     typedef typename FaceType::VertexType VertexType;
00062     typedef Pos<FaceType> PosType;
00064     typedef typename VertexType::ScalarType ScalarType;
00065 
00067     typename FaceType::FaceType *f;
00069     int z;
00071     VertexType *v;
00072 
00074     Pos() : f(0), z(-1), v(0) {}
00077     Pos(FaceType * const fp, int const zp, VertexType * const vp)
00078     {
00079         f=fp; z=zp; v=vp;
00080         assert((vp==fp->V0(zp))||(vp==fp->V1(zp)));
00081     }
00082     Pos(FaceType * const fp, int const zp){f=fp; z=zp; v=f->V(zp);}
00083     Pos(FaceType * const fp, VertexType * const vp)
00084     {
00085         f = fp;
00086         v = vp;
00087         for(int i = 0; i < f->VN(); ++i)
00088             if (f->V(i) == v) { z = f->Prev(i); break;}
00089     }
00090 
00091     // Official Access functions functions
00092     VertexType *& V(){ return v; }
00093     int         & E(){ return z; }
00094     FaceType   *& F(){ return f; }
00095 
00096     VertexType * V() const { return v; }
00097     int          E() const { return z; }
00098     FaceType   * F() const { return f; }
00099 
00100     // Returns the face index of the vertex inside the face.
00101     // Note that this is DIFFERENT from using the z member that denotes the edge index inside the face.
00102     // It should holds that Vind != (z+1)%3   &&   Vind == z || Vind = z+2%3
00103     int VInd() const
00104     {
00105         for(int i = 0; i < f->VN(); ++i) if(v==f->V(i)) return i;
00106         assert(0);
00107         return -1;
00108     }
00109 
00110 
00112     inline bool operator == ( PosType const & p ) const {
00113         return (f==p.f && z==p.z && v==p.v);
00114     }
00115 
00117     inline bool operator != ( PosType const & p ) const {
00118         return (f!=p.f || z!=p.z || v!=p.v);
00119     }
00121     inline bool operator <= ( PosType const & p) const {
00122         return  (f!=p.f)?(f<p.f):
00123                          (z!=p.z)?(z<p.z):
00124                                   (v<=p.v);
00125     }
00126 
00128     inline bool operator < ( PosType const & p) const {
00129         if ((*this)==p)return false;
00130         return ((*this)<=p);
00131     }
00132 
00134     inline PosType & operator = ( const PosType & h ){
00135         f=h.f;
00136         z=h.z;
00137         v=h.v;
00138         return *this;
00139     }
00140 
00142     void SetNull(){
00143         f=0;
00144         v=0;
00145         z=-1;
00146     }
00148     bool IsNull() const {
00149         return f==0 || v==0 || z<0;
00150     }
00151 
00152     //Cambia Faccia lungo z
00153     // e' uguale a FlipF solo che funziona anche per non manifold.
00155     void NextF()
00156     {
00157         FaceType * t = f;
00158         f = t->FFp(z);
00159         z = t->FFi(z);
00160     }
00161 
00162     // Paolo Cignoni 19/6/99
00163     // Si muove sulla faccia adiacente a f, lungo uno spigolo che
00164     // NON e' j, e che e' adiacente a v
00165     // in questo modo si scandiscono tutte le facce incidenti in un
00166     // vertice f facendo Next() finche' non si ritorna all'inizio
00167     // Nota che sul bordo rimbalza, cioe' se lo spigolo !=j e' di bordo
00168     // restituisce sempre la faccia f ma con nj che e' il nuovo spigolo di bordo
00169     // vecchi parametri:        FaceType * & f, VertexType * v, int & j
00170 
00172     void NextE()
00173     {
00174         assert( f->V(z)==v || f->V(f->Next(z))==v ); // L'edge j deve contenere v
00175         FlipE();
00176         FlipF();
00177         assert( f->V(z)==v || f->V(f->Next(z))==v );
00178     }
00179     // Cambia edge mantenendo la stessa faccia e lo stesso vertice
00181     void FlipE()
00182     {
00183         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v));
00184         if(f->V(f->Next(z))==v) z=f->Next(z);
00185         else z= f->Prev(z);
00186         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v));
00187     }
00188 
00189     // Cambia Faccia mantenendo lo stesso vertice e lo stesso edge
00190     // Vale che he.flipf.flipf= he
00191     // Se l'he e' di bordo he.flipf()==he
00192     // Si puo' usare SOLO se l'edge e' 2manifold altrimenti
00193     // si deve usare nextf
00194 
00196     void FlipF()
00197     {
00198         assert( f->FFp(z)->FFp(f->FFi(z))==f );  // two manifoldness check
00199         // Check that pos vertex is one of the current z-th edge and it is different from the vert opposite to the edge.
00200         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v));
00201         FaceType *nf=f->FFp(z);
00202         int nz=f->FFi(z);
00203         assert(nf->V(nf->Prev(nz))!=v && (nf->V(nf->Next(nz))==v || nf->V((nz))==v));
00204         f=nf;
00205         z=nz;
00206         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00207     }
00208 
00210     void FlipV()
00211     {
00212         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00213 
00214         if(f->V(f->Next(z))==v)
00215             v=f->V(z);
00216         else
00217             v=f->V(f->Next(z));
00218 
00219         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00220     }
00221 
00223     VertexType *VFlip() const
00224     {
00225         assert(f->cV(f->Prev(z))!=v && (f->cV(f->Next(z))==v || f->cV(z)==v));
00226         if(f->cV(f->Next(z))==v)        return f->cV(z);
00227         else                    return f->cV(f->Next(z));
00228     }
00229 
00231     FaceType *FFlip() const
00232     {
00233         //        assert( f->FFp(z)->FFp(f->FFi(z))==f );
00234         //        assert(f->V(f->Prev(z))!=v);
00235         //        assert(f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v);
00236         FaceType *nf=f->FFp(z);
00237         return nf;
00238     }
00239 
00240 
00241     // Trova il prossimo half-edge di bordo (nhe)
00242     // tale che
00243     // --nhe.f adiacente per vertice a he.f
00244     // --nhe.v adiacente per edge di bordo a he.v
00245     // l'idea e' che se he e' un half edge di bordo
00246     // si puo scorrere tutto un bordo facendo
00247     //
00248     //          hei=he;
00249     //          do
00250     //                  hei.Nextb()
00251     //          while(hei!=he);
00252 
00254     void NextB( )
00255     {
00256         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00257         assert(f->FFp(z)==f); // f is border along j
00258         // Si deve cambiare faccia intorno allo stesso vertice v
00259         //finche' non si trova una faccia di bordo.
00260         do
00261             NextE();
00262         while(!IsBorder());
00263 
00264         // L'edge j e' di bordo e deve contenere v
00265         assert(IsBorder() &&( f->V(z)==v || f->V(f->Next(z))==v ));
00266 
00267         FlipV();
00268         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00269         assert(f->FFp(z)==f); // f is border along j
00270     }
00271 
00273     void NextNotFaux( )
00274     {
00275         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00276         //assert(f->FFp(z)==f); // f is border along j
00277         // Si deve cambiare faccia intorno allo stesso vertice v
00278         //finche' non si trova una faccia di bordo.
00279         do
00280         {
00281             FlipE();
00282             if (IsFaux()) FlipF();
00283         }
00284         while(IsFaux());
00285 
00286         // L'edge j e' di bordo e deve contenere v
00287         assert((!IsFaux()) &&( f->V(z)==v || f->V(f->Next(z))==v ));
00288 
00289         FlipV();
00290         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00291         //assert(f->FFp(z)==f); // f is border along j
00292     }
00293 
00296     void NextCrease( )
00297     {
00298         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00299         assert(IsCrease()); // f is border along j
00300         // Si deve cambiare faccia intorno allo stesso vertice v
00301         //finche' non si trova una faccia di bordo.
00302         do
00303         {
00304             FlipE();
00305             if (!IsCrease()) FlipF();
00306         }
00307         while(!IsCrease());
00308 
00309         // L'edge j e' di bordo e deve contenere v
00310         assert(IsCrease() &&( f->V(z)==v || f->V(f->Next(z))==v ));
00311 
00312         FlipV();
00313         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00314     }
00315 
00317     bool IsBorder()const
00318     {
00319         return face::IsBorder(*f,z);
00320     }
00321 
00323     bool IsCrease() const
00324     {
00325         return f->IsCrease(z);
00326     }
00327 
00328     bool IsFaux() const
00329     {
00330         return (f->IsF(z));
00331     }
00332 
00333     bool IsManifold()
00334     {
00335         return face::IsManifold(*f,z);
00336     }
00337 
00341     int NumberOfIncidentVertices()
00342     {
00343         int  count               = 0;
00344         bool on_border = false;
00345         CheckIncidentFaces(count, on_border);
00346         if(on_border) return (count/2)+1;
00347         else                                    return count;
00348     }
00349 
00353     int NumberOfIncidentFaces()
00354     {
00355         int  count               = 0;
00356         bool on_border = false;
00357         CheckIncidentFaces(count, on_border);
00358         if(on_border) return count/2;
00359         else                                    return count;
00360     }
00361 
00362 
00363 
00368     int NumberOfFacesOnEdge() const
00369     {
00370         int  count               = 0;
00371         PosType ht = *this;
00372         do
00373         {
00374             ht.NextF();
00375             ++count;
00376         }
00377         while (ht!=*this);
00378         return count;
00379     }
00385     void Set(FaceType  * const fp, int const zp,  VertexType  * const vp)
00386     {
00387         f=fp;z=zp;v=vp;
00388         assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
00389     }
00390 
00391     void Set(FaceType  * const pFace, VertexType  * const pVertex)
00392     {
00393         f = pFace;
00394         v = pVertex;
00395         for(int i  = 0; i < f->VN(); ++i) if(f->V(i) == v ) {z = f->Prev(i);break;}
00396     }
00397 
00398     void Assert()
00399 #ifdef _DEBUG
00400     {
00401         FaceType ht=*this;
00402         ht.FlipF();
00403         ht.FlipF();
00404         assert(ht==*this);
00405 
00406         ht.FlipE();
00407         ht.FlipE();
00408         assert(ht==*this);
00409 
00410         ht.FlipV();
00411         ht.FlipV();
00412         assert(ht==*this);
00413     }
00414 #else
00415     {}
00416 #endif
00417 
00418 
00419 protected:
00420     void CheckIncidentFaces(int & count, bool & on_border)
00421     {
00422         PosType ht = *this;
00423         do
00424         {
00425             ++count;
00426             ht.NextE();
00427             if(ht.IsBorder()) on_border=true;
00428         } while (ht != *this);
00429     }
00430 };
00431 
00458 template <typename FaceType>
00459 class VFIterator
00460 {
00461 public:
00462 
00464     typedef typename FaceType::VertexType VertexType;
00466     typedef  FaceType  VFIFaceType;
00468     typedef typename VertexType::CoordType CoordType;
00470     typedef typename VertexType::ScalarType ScalarType;
00471 
00473     FaceType *f;
00475     int z;
00476 
00478     VFIterator() : f(0), z(-1) {}
00480     VFIterator(FaceType * _f,  const int &  _z){f = _f; z = _z;  assert(z>=0 && "VFAdj must be initialized");}
00481 
00483     VFIterator(VertexType * _v){f = _v->VFp(); z = _v->VFi(); assert(z>=0 && "VFAdj must be initialized");}
00484 
00485     VFIFaceType *&      F() { return f;}
00486     int &                                         I() { return z;}
00487 
00488     // Access to the vertex. Having a VFIterator vfi, it corresponds to
00489     // vfi.V() = vfi.F()->V(vfi.I())
00490     inline VertexType *V() const { return f->V(z);}
00491 
00492     inline VertexType * const & V0() const { return f->V0(z);}
00493     inline VertexType * const & V1() const { return f->V1(z);}
00494     inline VertexType * const & V2() const { return f->V2(z);}
00495 
00496     bool End() const {return f==0;}
00497     void operator++() {
00498         FaceType* t = f;
00499         f = t->VFp(z);
00500         z = t->VFi(z);
00501     }
00502 
00503 };
00504 
00506 }        // end namespace
00507 }        // end namespace
00508 #endif


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