flag.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 #ifndef __VCG_TRI_UPDATE_FLAGS
00024 #define __VCG_TRI_UPDATE_FLAGS
00025 
00026 #include <vcg/simplex/face/pos.h>
00027 
00028 namespace vcg {
00029 namespace tri {
00031 
00033 
00035 
00040 template <class UpdateMeshType>
00041 class UpdateFlags
00042 {
00043 
00044 public:
00045   typedef UpdateMeshType MeshType;
00046   typedef typename MeshType::ScalarType     ScalarType;
00047   typedef typename MeshType::VertexType     VertexType;
00048   typedef typename MeshType::VertexPointer  VertexPointer;
00049   typedef typename MeshType::VertexIterator VertexIterator;
00050   typedef typename MeshType::EdgeType       EdgeType;
00051   typedef typename MeshType::EdgePointer    EdgePointer;
00052   typedef typename MeshType::EdgeIterator   EdgeIterator;
00053   typedef typename MeshType::FaceType       FaceType;
00054   typedef typename MeshType::FacePointer    FacePointer;
00055   typedef typename MeshType::FaceIterator   FaceIterator;
00056 
00058 
00059   static void Clear(MeshType &m)
00060   {
00061     if(HasPerVertexFlags(m) )
00062       for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00063         (*vi).Flags() = 0;
00064     if(HasPerEdgeFlags(m) )
00065       for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00066         (*ei).Flags() = 0;
00067     if(HasPerFaceFlags(m) )
00068       for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00069         (*fi).Flags() = 0;
00070   }
00071 
00072   static void VertexClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
00073   {
00074     RequirePerVertexFlags(m);
00075     int andMask = ~FlagMask;
00076     for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00077       if(!(*vi).IsD()) (*vi).Flags() &= andMask ;
00078   }
00079 
00080   static void EdgeClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
00081   {
00082     RequirePerEdgeFlags(m);
00083     int andMask = ~FlagMask;
00084     for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00085       if(!(*ei).IsD()) (*ei).Flags() &= andMask ;
00086   }
00087 
00088   static void FaceClear(MeshType &m, unsigned int FlagMask = 0xffffffff)
00089   {
00090     RequirePerFaceFlags(m);
00091     int andMask = ~FlagMask;
00092     for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00093       if(!(*fi).IsD()) (*fi).Flags() &= andMask ;
00094   }
00095 
00096   static void VertexSet(MeshType &m, unsigned int FlagMask)
00097   {
00098     RequirePerVertexFlags(m);
00099     for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi)
00100       if(!(*vi).IsD()) (*vi).Flags() |= FlagMask ;
00101   }
00102 
00103   static void EdgeSet(MeshType &m, unsigned int FlagMask)
00104   {
00105     RequirePerEdgeFlags(m);
00106     for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei)
00107       if(!(*ei).IsD()) (*ei).Flags() |= FlagMask ;
00108   }
00109 
00110   static void FaceSet(MeshType &m, unsigned int FlagMask)
00111   {
00112     RequirePerFaceFlags(m);
00113     for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
00114       if(!(*fi).IsD()) (*fi).Flags() |= FlagMask ;
00115   }
00116 
00117 
00118 
00119   static void VertexClearV(MeshType &m) { VertexClear(m,VertexType::VISITED);}
00120   static void VertexClearS(MeshType &m) { VertexClear(m,VertexType::SELECTED);}
00121   static void VertexClearB(MeshType &m) { VertexClear(m,VertexType::BORDER);}
00122   static void EdgeClearV(MeshType &m) { EdgeClear(m,EdgeType::VISITED);}
00123   static void FaceClearV(MeshType &m) { FaceClear(m,FaceType::VISITED);}
00124   static void FaceClearB(MeshType &m) { FaceClear(m,FaceType::BORDER012);}
00125   static void FaceClearS(MeshType &m) {FaceClear(m,FaceType::SELECTED);}
00126   static void FaceClearF(MeshType &m) { FaceClear(m,FaceType::FAUX012);}
00127   static void FaceClearCreases(MeshType &m) { FaceClear(m,FaceType::CREASE0);
00128                                               FaceClear(m,FaceType::CREASE1);
00129                                               FaceClear(m,FaceType::CREASE2);
00130                                             }
00131 
00132   static void EdgeSetV(MeshType &m) { EdgeSet(m,EdgeType::VISITED);}
00133   static void VertexSetV(MeshType &m) { VertexSet(m,VertexType::VISITED);}
00134   static void VertexSetS(MeshType &m) { VertexSet(m,VertexType::SELECTED);}
00135   static void VertexSetB(MeshType &m) { VertexSet(m,VertexType::BORDER);}
00136   static void FaceSetV(MeshType &m) { FaceSet(m,FaceType::VISITED);}
00137   static void FaceSetB(MeshType &m) { FaceSet(m,FaceType::BORDER);}
00138   static void FaceSetF(MeshType &m) { FaceSet(m,FaceType::FAUX012);}
00139 
00141 
00145   static void FaceBorderFromFF(MeshType &m)
00146   {
00147     RequirePerFaceFlags(m);
00148     RequireFFAdjacency(m);
00149 
00150     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)if(!(*fi).IsD())
00151       for(int j=0;j<fi->VN();++j)
00152       {
00153         if(face::IsBorder(*fi,j)) (*fi).SetB(j);
00154         else (*fi).ClearB(j);
00155       }
00156   }
00157 
00158 
00159   static void FaceBorderFromVF(MeshType &m)
00160   {
00161     RequirePerFaceFlags(m);
00162     RequireVFAdjacency(m);
00163 
00164     FaceClearB(m);
00165     int visitedBit=VertexType::NewBitFlag();
00166 
00167     // Calcolo dei bordi
00168     // per ogni vertice vi si cercano i vertici adiacenti che sono toccati da una faccia sola
00169     // (o meglio da un numero dispari di facce)
00170 
00171     const int BORDERFLAG[3]={FaceType::BORDER0, FaceType::BORDER1, FaceType::BORDER2};
00172 
00173     for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00174       if(!(*vi).IsD())
00175       {
00176         for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
00177         {
00178           vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
00179           vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
00180         }
00181         for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
00182         {
00183           if(vfi.f->V1(vfi.z)->IsUserBit(visitedBit))  vfi.f->V1(vfi.z)->ClearUserBit(visitedBit);
00184           else vfi.f->V1(vfi.z)->SetUserBit(visitedBit);
00185           if(vfi.f->V2(vfi.z)->IsUserBit(visitedBit))  vfi.f->V2(vfi.z)->ClearUserBit(visitedBit);
00186           else vfi.f->V2(vfi.z)->SetUserBit(visitedBit);
00187         }
00188         for(face::VFIterator<FaceType> vfi(&*vi) ; !vfi.End(); ++vfi )
00189         {
00190           if(vfi.f->V(vfi.z)< vfi.f->V1(vfi.z)  &&  vfi.f->V1(vfi.z)->IsUserBit(visitedBit))
00191             vfi.f->Flags() |= BORDERFLAG[vfi.z];
00192           if(vfi.f->V(vfi.z)< vfi.f->V2(vfi.z)  &&  vfi.f->V2(vfi.z)->IsUserBit(visitedBit))
00193             vfi.f->Flags() |= BORDERFLAG[(vfi.z+2)%3];
00194         }
00195       }
00196     VertexType::DeleteBitFlag(visitedBit);
00197   }
00198 
00199 
00200   class EdgeSorter
00201   {
00202   public:
00203 
00204     VertexPointer v[2];         // Puntatore ai due vertici (Ordinati)
00205     FacePointer    f;                           // Puntatore alla faccia generatrice
00206     int      z;                         // Indice dell'edge nella faccia
00207 
00208     EdgeSorter() {} // Nothing to do
00209 
00210 
00211     void Set( const FacePointer pf, const int nz )
00212     {
00213       assert(pf!=0);
00214       assert(nz>=0);
00215       assert(nz<3);
00216 
00217       v[0] = pf->V(nz);
00218       v[1] = pf->V((nz+1)%3);
00219       assert(v[0] != v[1]);
00220 
00221       if( v[0] > v[1] ) std::swap(v[0],v[1]);
00222       f    = pf;
00223       z    = nz;
00224     }
00225 
00226     inline bool operator <  ( const EdgeSorter & pe ) const {
00227       if( v[0]<pe.v[0] ) return true;
00228       else if( v[0]>pe.v[0] ) return false;
00229       else return v[1] < pe.v[1];
00230     }
00231 
00232     inline bool operator == ( const EdgeSorter & pe ) const
00233     {
00234       return v[0]==pe.v[0] && v[1]==pe.v[1];
00235     }
00236     inline bool operator != ( const EdgeSorter & pe ) const
00237     {
00238       return v[0]!=pe.v[0] || v[1]!=pe.v[1];
00239     }
00240 
00241   };
00242 
00243 
00244   // versione minimale che non calcola i complex flag.
00245   static void VertexBorderFromNone(MeshType &m)
00246   {
00247     RequirePerVertexFlags(m);
00248 
00249     std::vector<EdgeSorter> e;
00250     typename UpdateMeshType::FaceIterator pf;
00251     typename std::vector<EdgeSorter>::iterator p;
00252 
00253     if( m.fn == 0 )
00254       return;
00255 
00256     e.resize(m.fn*3);                                                           // Alloco il vettore ausiliario
00257     p = e.begin();
00258     for(pf=m.face.begin();pf!=m.face.end();++pf)                        // Lo riempio con i dati delle facce
00259       if( ! (*pf).IsD() )
00260         for(int j=0;j<3;++j)
00261         {
00262           (*p).Set(&(*pf),j);
00263           (*pf).ClearB(j);
00264           ++p;
00265         }
00266     assert(p==e.end());
00267     sort(e.begin(), e.end());                                                   // Lo ordino per vertici
00268 
00269     typename std::vector<EdgeSorter>::iterator pe,ps;
00270     for(ps = e.begin(), pe = e.begin(); pe < e.end(); ++pe)     // Scansione vettore ausiliario
00271     {
00272       if( pe==e.end() ||  *pe != *ps )                                  // Trovo blocco di edge uguali
00273       {
00274         if(pe-ps==1)    {
00275           ps->v[0]->SetB();
00276           ps->v[1]->SetB();
00277         }/* else
00278           if(pe-ps!=2)  {  // not twomanyfold!
00279             for(;ps!=pe;++ps) {
00280               ps->v[0]->SetB(); // Si settano border anche i complex.
00281               ps->v[1]->SetB();
00282             }
00283           }*/
00284         ps = pe;
00285       }
00286     }
00287   }
00288 
00291   static void FaceBorderFromNone(MeshType &m)
00292   {
00293     RequirePerFaceFlags(m);
00294 
00295     std::vector<EdgeSorter> e;
00296     typename UpdateMeshType::FaceIterator pf;
00297     typename std::vector<EdgeSorter>::iterator p;
00298 
00299     for(VertexIterator v=m.vert.begin();v!=m.vert.end();++v)
00300       (*v).ClearB();
00301 
00302     if( m.fn == 0 )
00303       return;
00304 
00305     FaceIterator fi;
00306     int n_edges = 0;
00307     for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
00308     e.resize(n_edges);
00309 
00310     p = e.begin();
00311     for(pf=m.face.begin();pf!=m.face.end();++pf)                        // Lo riempio con i dati delle facce
00312       if( ! (*pf).IsD() )
00313         for(int j=0;j<(*pf).VN();++j)
00314         {
00315           (*p).Set(&(*pf),j);
00316           (*pf).ClearB(j);
00317           ++p;
00318         }
00319     assert(p==e.end());
00320     sort(e.begin(), e.end());                                                   // Lo ordino per vertici
00321 
00322     typename std::vector<EdgeSorter>::iterator pe,ps;
00323     ps = e.begin();pe=e.begin();
00324     do
00325     {
00326       if( pe==e.end() ||  *pe != *ps )                                  // Trovo blocco di edge uguali
00327       {
00328         if(pe-ps==1)    {
00329           ps->f->SetB(ps->z);
00330         } /*else
00331           if(pe-ps!=2)  {  // Caso complex!!
00332             for(;ps!=pe;++ps)
00333               ps->f->SetB(ps->z); // Si settano border anche i complex.
00334           }*/
00335         ps = pe;
00336       }
00337       if(pe==e.end()) break;
00338       ++pe;
00339     } while(true);
00340     //  TRACE("found %i border (%i complex) on %i edges\n",nborder,ncomplex,ne);
00341   }
00342 
00344   static void VertexBorderFromFaceAdj(MeshType &m)
00345 {
00346     RequirePerFaceFlags(m);
00347     RequirePerVertexFlags(m);
00348     RequireFFAdjacency(m);
00349     // MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
00350 
00351     VertexClearB(m);
00352     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00353       if(!(*fi).IsD())
00354       {
00355 
00356         for(int z=0;z<(*fi).VN();++z)
00357           if( face::IsBorder(*fi,z))
00358           {
00359             (*fi).V0(z)->SetB();
00360             (*fi).V1(z)->SetB();
00361           }
00362       }
00363   }
00364 
00366   static void VertexBorderFromFaceBorder(MeshType &m)
00367   {
00368     RequirePerFaceFlags(m);
00369     RequirePerVertexFlags(m);
00370     VertexClearB(m);
00371     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00372       if(!(*fi).IsD())
00373       {
00374         for(int z=0;z<(*fi).VN();++z)
00375           if( (*fi).IsB(z) )
00376           {
00377             (*fi).V(z)->SetB();
00378             (*fi).V((*fi).Next(z))->SetB();
00379           }
00380       }
00381   }
00382 
00383 
00393   static void FaceFauxSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
00394   {
00395     RequirePerFaceFlags(m);
00396     RequireFFAdjacency(m);
00397     //initially Nothing is faux (e.g all crease)
00398     FaceClearF(m);
00399     // Then mark faux only if the signed angle is the range.
00400     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
00401     {
00402       for(int z=0;z<(*fi).VN();++z)
00403       {
00404         if(!face::IsBorder(*fi,z) )
00405         {
00406           ScalarType angle = DihedralAngleRad(*fi,z);
00407           if(angle>AngleRadNeg && angle<AngleRadPos)
00408             (*fi).SetF(z);
00409         }
00410         else
00411         {
00412           if(MarkBorderFlag) (*fi).SetF(z);
00413         }
00414       }
00415     }
00416   }
00417 
00421   static void FaceFauxBorder(MeshType &m)
00422   {
00423     RequirePerFaceFlags(m);
00424     RequireFFAdjacency(m);
00425     //initially Nothing is faux (e.g all crease)
00426     FaceClearF(m);
00427     // Then mark faux only if the signed angle is the range.
00428     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
00429     {
00430       for(int z=0;z<(*fi).VN();++z)
00431       {
00432         if(!face::IsBorder(*fi,z) ) (*fi).SetF(z);
00433       }
00434     }
00435   }
00436 
00441   static void FaceFauxCrease(MeshType &m,float AngleRad)
00442   {
00443     FaceFauxSignedCrease(m,-AngleRad,AngleRad);
00444   }
00445 
00446 }; // end class
00447 
00448 }       // End namespace tri
00449 }       // End namespace vcg
00450 
00451 
00452 #endif


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