From c3beef6091a35b7c407032b866e73cd393c3fcdd Mon Sep 17 00:00:00 2001 From: nicopietroni Date: Thu, 11 Sep 2014 20:43:41 +0000 Subject: [PATCH] added NextNotFaux function --- vcg/simplex/face/pos.h | 615 +++++++++++++++++++++-------------------- 1 file changed, 321 insertions(+), 294 deletions(-) diff --git a/vcg/simplex/face/pos.h b/vcg/simplex/face/pos.h index d970734e..9bcd6d9d 100644 --- a/vcg/simplex/face/pos.h +++ b/vcg/simplex/face/pos.h @@ -44,10 +44,10 @@ template bool IsManifold(FaceType const & f, const int j ); /** Templated over the class face, it stores a \em position over a face in a mesh. - It contain a pointer to the current face, - the index of one edge and a pointer to one of the vertices of the edge. - See also the JumpingPos in jumping_pos.h for an iterator that loops - around the faces of a vertex without requiring the VF topology. + It contain a pointer to the current face, + the index of one edge and a pointer to one of the vertices of the edge. + See also the JumpingPos in jumping_pos.h for an iterator that loops + around the faces of a vertex without requiring the VF topology. */ @@ -56,266 +56,293 @@ class Pos { public: - /// The vertex type - typedef typename FaceType::VertexType VertexType; - ///The Pos type - typedef Pos PosType; - /// The scalar type - typedef typename VertexType::ScalarType ScalarType; + /// The vertex type + typedef typename FaceType::VertexType VertexType; + ///The Pos type + typedef Pos PosType; + /// The scalar type + typedef typename VertexType::ScalarType ScalarType; - /// Pointer to the face of the half-edge - typename FaceType::FaceType *f; - /// Index of the edge - int z; - /// Pointer to the vertex - VertexType *v; + /// Pointer to the face of the half-edge + typename FaceType::FaceType *f; + /// Index of the edge + int z; + /// Pointer to the vertex + VertexType *v; - /// Default constructor - Pos() : f(0), z(-1), v(0) {} - /// Constructor which associates the half-edge element with a face, its edge and its vertex - /// \note that the input must be consistent, e.g. it should hold that \c vp==fp->V0(zp) or \c vp==fp->V1(zp) - Pos(FaceType * const fp, int const zp, VertexType * const vp) - { - f=fp; z=zp; v=vp; - assert((vp==fp->V0(zp))||(vp==fp->V1(zp))); - } - Pos(FaceType * const fp, int const zp){f=fp; z=zp; v=f->V(zp);} - Pos(FaceType * const fp, VertexType * const vp) - { - f = fp; - v = vp; - for(int i = 0; i < f->VN(); ++i) - if (f->V(i) == v) { z = f->Prev(i); break;} - } + /// Default constructor + Pos() : f(0), z(-1), v(0) {} + /// Constructor which associates the half-edge element with a face, its edge and its vertex + /// \note that the input must be consistent, e.g. it should hold that \c vp==fp->V0(zp) or \c vp==fp->V1(zp) + Pos(FaceType * const fp, int const zp, VertexType * const vp) + { + f=fp; z=zp; v=vp; + assert((vp==fp->V0(zp))||(vp==fp->V1(zp))); + } + Pos(FaceType * const fp, int const zp){f=fp; z=zp; v=f->V(zp);} + Pos(FaceType * const fp, VertexType * const vp) + { + f = fp; + v = vp; + for(int i = 0; i < f->VN(); ++i) + if (f->V(i) == v) { z = f->Prev(i); break;} + } // Official Access functions functions - VertexType *& V(){ return v; } - int & E(){ return z; } - FaceType *& F(){ return f; } + VertexType *& V(){ return v; } + int & E(){ return z; } + FaceType *& F(){ return f; } - VertexType * V() const { return v; } - int E() const { return z; } - FaceType * F() const { return f; } + VertexType * V() const { return v; } + int E() const { return z; } + FaceType * F() const { return f; } -// Returns the face index of the vertex inside the face. -// Note that this is DIFFERENT from using the z member that denotes the edge index inside the face. -// It should holds that Vind != (z+1)%3 && Vind == z || Vind = z+2%3 - int VInd() - { - for(int i = 0; i < f->VN(); ++i) if(v==f->V(i)) return i; - assert(0); - return -1; - } + // Returns the face index of the vertex inside the face. + // Note that this is DIFFERENT from using the z member that denotes the edge index inside the face. + // It should holds that Vind != (z+1)%3 && Vind == z || Vind = z+2%3 + int VInd() + { + for(int i = 0; i < f->VN(); ++i) if(v==f->V(i)) return i; + assert(0); + return -1; + } - /// Operator to compare two half-edge - inline bool operator == ( PosType const & p ) const { - return (f==p.f && z==p.z && v==p.v); - } + /// Operator to compare two half-edge + inline bool operator == ( PosType const & p ) const { + return (f==p.f && z==p.z && v==p.v); + } - /// Operator to compare two half-edge - inline bool operator != ( PosType const & p ) const { - return (f!=p.f || z!=p.z || v!=p.v); - } - /// Operator to order half-edge; it's compare at the first the face pointers, then the index of the edge and finally the vertex pointers - inline bool operator <= ( PosType const & p) const { - return (f!=p.f)?(fFFp(z); - z = t->FFi(z); - } + //Cambia Faccia lungo z + // e' uguale a FlipF solo che funziona anche per non manifold. + /// Change face via z + void NextF() + { + FaceType * t = f; + f = t->FFp(z); + z = t->FFi(z); + } - // Paolo Cignoni 19/6/99 - // Si muove sulla faccia adiacente a f, lungo uno spigolo che - // NON e' j, e che e' adiacente a v - // in questo modo si scandiscono tutte le facce incidenti in un - // vertice f facendo Next() finche' non si ritorna all'inizio - // Nota che sul bordo rimbalza, cioe' se lo spigolo !=j e' di bordo - // restituisce sempre la faccia f ma con nj che e' il nuovo spigolo di bordo - // vecchi parametri: FaceType * & f, VertexType * v, int & j + // Paolo Cignoni 19/6/99 + // Si muove sulla faccia adiacente a f, lungo uno spigolo che + // NON e' j, e che e' adiacente a v + // in questo modo si scandiscono tutte le facce incidenti in un + // vertice f facendo Next() finche' non si ritorna all'inizio + // Nota che sul bordo rimbalza, cioe' se lo spigolo !=j e' di bordo + // restituisce sempre la faccia f ma con nj che e' il nuovo spigolo di bordo + // vecchi parametri: FaceType * & f, VertexType * v, int & j - /// It moves on the adjacent face incident to v, via a different edge that j - void NextE() - { - assert( f->V(z)==v || f->V(f->Next(z))==v ); // L'edge j deve contenere v - FlipE(); - FlipF(); - assert( f->V(z)==v || f->V(f->Next(z))==v ); - } - // Cambia edge mantenendo la stessa faccia e lo stesso vertice - /// Changes edge maintaining the same face and the same vertex - void FlipE() - { - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v)); - if(f->V(f->Next(z))==v) z=f->Next(z); - else z= f->Prev(z); - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v)); - } + /// It moves on the adjacent face incident to v, via a different edge that j + void NextE() + { + assert( f->V(z)==v || f->V(f->Next(z))==v ); // L'edge j deve contenere v + FlipE(); + FlipF(); + assert( f->V(z)==v || f->V(f->Next(z))==v ); + } + // Cambia edge mantenendo la stessa faccia e lo stesso vertice + /// Changes edge maintaining the same face and the same vertex + void FlipE() + { + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v)); + if(f->V(f->Next(z))==v) z=f->Next(z); + else z= f->Prev(z); + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v)); + } - // Cambia Faccia mantenendo lo stesso vertice e lo stesso edge - // Vale che he.flipf.flipf= he - // Se l'he e' di bordo he.flipf()==he - // Si puo' usare SOLO se l'edge e' 2manifold altrimenti - // si deve usare nextf + // Cambia Faccia mantenendo lo stesso vertice e lo stesso edge + // Vale che he.flipf.flipf= he + // Se l'he e' di bordo he.flipf()==he + // Si puo' usare SOLO se l'edge e' 2manifold altrimenti + // si deve usare nextf - /// Changes face maintaining the same vertex and the same edge - void FlipF() - { - assert( f->FFp(z)->FFp(f->FFi(z))==f ); // two manifoldness check - // Check that pos vertex is one of the current z-th edge and it is different from the vert opposite to the edge. - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v)); - FaceType *nf=f->FFp(z); - int nz=f->FFi(z); - assert(nf->V(nf->Prev(nz))!=v && (nf->V(nf->Next(nz))==v || nf->V((nz))==v)); - f=nf; - z=nz; - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); - } + /// Changes face maintaining the same vertex and the same edge + void FlipF() + { + assert( f->FFp(z)->FFp(f->FFi(z))==f ); // two manifoldness check + // Check that pos vertex is one of the current z-th edge and it is different from the vert opposite to the edge. + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v)); + FaceType *nf=f->FFp(z); + int nz=f->FFi(z); + assert(nf->V(nf->Prev(nz))!=v && (nf->V(nf->Next(nz))==v || nf->V((nz))==v)); + f=nf; + z=nz; + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + } - /// Changes vertex maintaining the same face and the same edge - void FlipV() - { - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + /// Changes vertex maintaining the same face and the same edge + void FlipV() + { + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); - if(f->V(f->Next(z))==v) - v=f->V(z); - else - v=f->V(f->Next(z)); + if(f->V(f->Next(z))==v) + v=f->V(z); + else + v=f->V(f->Next(z)); - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); - } + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + } - /// return the vertex that it should have if we make FlipV; + /// return the vertex that it should have if we make FlipV; VertexType *VFlip() const { assert(f->cV(f->Prev(z))!=v && (f->cV(f->Next(z))==v || f->cV(z)==v)); if(f->cV(f->Next(z))==v) return f->cV(z); - else return f->cV(f->Next(z)); + else return f->cV(f->Next(z)); } - /// return the face that it should have if we make FlipF; + /// return the face that it should have if we make FlipF; FaceType *FFlip() const { -// assert( f->FFp(z)->FFp(f->FFi(z))==f ); -// assert(f->V(f->Prev(z))!=v); -// assert(f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v); + // assert( f->FFp(z)->FFp(f->FFi(z))==f ); + // assert(f->V(f->Prev(z))!=v); + // assert(f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v); FaceType *nf=f->FFp(z); return nf; - } - - - // Trova il prossimo half-edge di bordo (nhe) - // tale che - // --nhe.f adiacente per vertice a he.f - // --nhe.v adiacente per edge di bordo a he.v - // l'idea e' che se he e' un half edge di bordo - // si puo scorrere tutto un bordo facendo - // - // hei=he; - // do - // hei.Nextb() - // while(hei!=he); - - /// Finds the next half-edge border - void NextB( ) - { - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); - assert(f->FFp(z)==f); // f is border along j - // Si deve cambiare faccia intorno allo stesso vertice v - //finche' non si trova una faccia di bordo. - do - NextE(); - while(!IsBorder()); - - // L'edge j e' di bordo e deve contenere v - assert(IsBorder() &&( f->V(z)==v || f->V(f->Next(z))==v )); - - FlipV(); - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); - assert(f->FFp(z)==f); // f is border along j - } - - /// Checks if the half-edge is of border - bool IsBorder() - { - return face::IsBorder(*f,z); - } - - bool IsManifold() - { - return face::IsManifold(*f,z); } - /*! - * Returns the number of vertices incident on the vertex pos is currently pointing to. - */ - int NumberOfIncidentVertices() - { - int count = 0; - bool on_border = false; - CheckIncidentFaces(count, on_border); - if(on_border) return (count/2)+1; - else return count; - } - /*! - * Returns the number of faces incident on the vertex pos is currently pointing to. - */ - int NumberOfIncidentFaces() - { - int count = 0; - bool on_border = false; - CheckIncidentFaces(count, on_border); - if(on_border) return count/2; - else return count; - } + // Trova il prossimo half-edge di bordo (nhe) + // tale che + // --nhe.f adiacente per vertice a he.f + // --nhe.v adiacente per edge di bordo a he.v + // l'idea e' che se he e' un half edge di bordo + // si puo scorrere tutto un bordo facendo + // + // hei=he; + // do + // hei.Nextb() + // while(hei!=he); + + /// Finds the next half-edge border + void NextB( ) + { + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + assert(f->FFp(z)==f); // f is border along j + // Si deve cambiare faccia intorno allo stesso vertice v + //finche' non si trova una faccia di bordo. + do + NextE(); + while(!IsBorder()); + + // L'edge j e' di bordo e deve contenere v + assert(IsBorder() &&( f->V(z)==v || f->V(f->Next(z))==v )); + + FlipV(); + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + assert(f->FFp(z)==f); // f is border along j + } + + /// Finds the next half-edge border + void NextNotFaux( ) + { + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + //assert(f->FFp(z)==f); // f is border along j + // Si deve cambiare faccia intorno allo stesso vertice v + //finche' non si trova una faccia di bordo. + do + { + FlipE(); + if (IsFaux()) FlipF(); + } + while(IsFaux()); + + // L'edge j e' di bordo e deve contenere v + assert((!IsFaux()) &&( f->V(z)==v || f->V(f->Next(z))==v )); + + FlipV(); + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); + //assert(f->FFp(z)==f); // f is border along j + } + + /// Checks if the half-edge is of border + bool IsBorder() + { + return face::IsBorder(*f,z); + } + + bool IsFaux() + { + return (f->IsF(z)); + } + + bool IsManifold() + { + return face::IsManifold(*f,z); + } + + /*! + * Returns the number of vertices incident on the vertex pos is currently pointing to. + */ + int NumberOfIncidentVertices() + { + int count = 0; + bool on_border = false; + CheckIncidentFaces(count, on_border); + if(on_border) return (count/2)+1; + else return count; + } + + /*! + * Returns the number of faces incident on the vertex pos is currently pointing to. + */ + int NumberOfIncidentFaces() + { + int count = 0; + bool on_border = false; + CheckIncidentFaces(count, on_border); + if(on_border) return count/2; + else return count; + } - /*! + /*! * Returns the number of faces incident on the edge the pos is currently pointing to. * useful to compute the complexity of a non manifold edge */ - int NumberOfFacesOnEdge() const - { - int count = 0; - PosType ht = *this; - do + int NumberOfFacesOnEdge() const { - ht.NextF(); - ++count; + int count = 0; + PosType ht = *this; + do + { + ht.NextF(); + ++count; + } + while (ht!=*this); + return count; } - while (ht!=*this); - return count; - } /** Function to inizialize an half-edge. @param fp Puntatore alla faccia @param zp Indice dell'edge @@ -327,45 +354,45 @@ public: assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v)); } - void Set(FaceType * const pFace, VertexType * const pVertex) - { - f = pFace; - v = pVertex; - for(int i = 0; i < f->VN(); ++i) if(f->V(i) == v ) {z = f->Prev(i);break;} - } + void Set(FaceType * const pFace, VertexType * const pVertex) + { + f = pFace; + v = pVertex; + for(int i = 0; i < f->VN(); ++i) if(f->V(i) == v ) {z = f->Prev(i);break;} + } - void Assert() - #ifdef _DEBUG - { - FaceType ht=*this; - ht.FlipF(); - ht.FlipF(); - assert(ht==*this); + void Assert() +#ifdef _DEBUG + { + FaceType ht=*this; + ht.FlipF(); + ht.FlipF(); + assert(ht==*this); - ht.FlipE(); - ht.FlipE(); - assert(ht==*this); + ht.FlipE(); + ht.FlipE(); + assert(ht==*this); - ht.FlipV(); - ht.FlipV(); - assert(ht==*this); - } - #else - {} - #endif + ht.FlipV(); + ht.FlipV(); + assert(ht==*this); + } +#else + {} +#endif - protected: - void CheckIncidentFaces(int & count, bool & on_border) - { - PosType ht = *this; - do - { - ++count; - ht.NextE(); - if(ht.IsBorder()) on_border=true; - } while (ht != *this); - } +protected: + void CheckIncidentFaces(int & count, bool & on_border) + { + PosType ht = *this; + do + { + ++count; + ht.NextE(); + if(ht.IsBorder()) on_border=true; + } while (ht != *this); + } }; /** Class VFIterator. @@ -382,15 +409,15 @@ public: // Alternative - vcg::face::VFIterator vfi(f, 1); - while (!vfi.End()){ - vfi.F()->ClearV(); - ++vfi; - } + vcg::face::VFIterator vfi(f, 1); + while (!vfi.End()){ + vfi.F()->ClearV(); + ++vfi; + } - See also the JumpingPos in jumping_pos.h for an iterator that loops - around the faces of a vertex using FF topology and without requiring the VF topology. + See also the JumpingPos in jumping_pos.h for an iterator that loops + around the faces of a vertex using FF topology and without requiring the VF topology. */ @@ -399,45 +426,45 @@ class VFIterator { public: - /// The vertex type - typedef typename FaceType::VertexType VertexType; - /// The Base face type - typedef FaceType VFIFaceType; - /// The vector type - typedef typename VertexType::CoordType CoordType; - /// The scalar type - typedef typename VertexType::ScalarType ScalarType; + /// The vertex type + typedef typename FaceType::VertexType VertexType; + /// The Base face type + typedef FaceType VFIFaceType; + /// The vector type + typedef typename VertexType::CoordType CoordType; + /// The scalar type + typedef typename VertexType::ScalarType ScalarType; - /// Pointer to the face of the half-edge - FaceType *f; - /// Index of the vertex - int z; + /// Pointer to the face of the half-edge + FaceType *f; + /// Index of the vertex + int z; - /// Default constructor - VFIterator() : f(0), z(-1) {} - /// Constructor which associates the half-edge elementet with a face and its vertex - VFIterator(FaceType * _f, const int & _z){f = _f; z = _z; assert(z>=0 && "VFAdj must be initialized");} + /// Default constructor + VFIterator() : f(0), z(-1) {} + /// Constructor which associates the half-edge elementet with a face and its vertex + VFIterator(FaceType * _f, const int & _z){f = _f; z = _z; assert(z>=0 && "VFAdj must be initialized");} - /// Constructor which takes a pointer to vertex - VFIterator(VertexType * _v){f = _v->VFp(); z = _v->VFi(); assert(z>=0 && "VFAdj must be initialized");} + /// Constructor which takes a pointer to vertex + VFIterator(VertexType * _v){f = _v->VFp(); z = _v->VFi(); assert(z>=0 && "VFAdj must be initialized");} - VFIFaceType *& F() { return f;} - int & I() { return z;} + VFIFaceType *& F() { return f;} + int & I() { return z;} - // Access to the vertex. Having a VFIterator vfi, it corresponds to - // vfi.V() = vfi.F()->V(vfi.I()) - inline VertexType *V() const { return f->V(z);} + // Access to the vertex. Having a VFIterator vfi, it corresponds to + // vfi.V() = vfi.F()->V(vfi.I()) + inline VertexType *V() const { return f->V(z);} - inline VertexType * const & V0() const { return f->V0(z);} - inline VertexType * const & V1() const { return f->V1(z);} - inline VertexType * const & V2() const { return f->V2(z);} + inline VertexType * const & V0() const { return f->V0(z);} + inline VertexType * const & V1() const { return f->V1(z);} + inline VertexType * const & V2() const { return f->V2(z);} - bool End() const {return f==0;} - void operator++() { - FaceType* t = f; + bool End() const {return f==0;} + void operator++() { + FaceType* t = f; f = t->VFp(z); z = t->VFi(z); - } + } };