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_TRI_UPDATE_TOPOLOGY
00025 #define __VCG_TRI_UPDATE_TOPOLOGY
00026 #include <algorithm>
00027 #include <vector>
00028 #include <vcg/simplex/face/pos.h>
00029 #include <vcg/simplex/face/topology.h>
00030 #include <vcg/simplex/edge/topology.h>
00031 
00032 namespace vcg {
00033 namespace tri {
00035 
00037 
00039 
00040 template <class UpdateMeshType>
00041 class UpdateTopology
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 
00057 
00059 
00061 
00065 class PEdge
00066 {
00067 public:
00068 
00069   VertexPointer  v[2];  // the two Vertex pointer are ordered!
00070   FacePointer    f;     // the face where this edge belong
00071   int            z;     // index in [0..2] of the edge of the face
00072 
00073   PEdge() {}
00074   PEdge(FacePointer  pf, const int nz) { this->Set(pf,nz); }
00075   void Set( FacePointer  pf, const int nz )
00076   {
00077     assert(pf!=0);
00078     assert(nz>=0);
00079     assert(nz<pf->VN());
00080 
00081     v[0] = pf->V(nz);
00082     v[1] = pf->V(pf->Next(nz));
00083     assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
00084 
00085     if( v[0] > v[1] ) std::swap(v[0],v[1]);
00086     f    = pf;
00087     z    = nz;
00088   }
00089 
00090   inline bool operator <  ( const PEdge & pe ) const
00091   {
00092     if( v[0]<pe.v[0] ) return true;
00093     else if( v[0]>pe.v[0] ) return false;
00094     else return v[1] < pe.v[1];
00095   }
00096 
00097   inline bool operator == ( const PEdge & pe ) const
00098   {
00099     return v[0]==pe.v[0] && v[1]==pe.v[1];
00100   }
00103   inline Point3<ScalarType> EdgeBarycentricToFaceBarycentric(ScalarType u) const
00104   {
00105     Point3<ScalarType> interp(0,0,0);
00106     interp[ this->z     ] = u;
00107     interp[(this->z+1)%3] = 1.0f-u;
00108     return interp;
00109   }
00110 };
00111 
00115 
00116 static void FillEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec, bool includeFauxEdge=true)
00117 {
00118   edgeVec.reserve(m.fn*3);
00119   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00120     if( ! (*fi).IsD() )
00121       for(int j=0;j<(*fi).VN();++j)
00122         if(includeFauxEdge || !(*fi).IsF(j))
00123           edgeVec.push_back(PEdge(&*fi,j));
00124 }
00125 
00126 static void FillUniqueEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec, bool includeFauxEdge=true)
00127 {
00128     FillEdgeVector(m,edgeVec,includeFauxEdge);
00129     sort(edgeVec.begin(), edgeVec.end());               // Lo ordino per vertici
00130 
00131     typename std::vector< PEdge>::iterator newEnd = std::unique(edgeVec.begin(), edgeVec.end());
00132 
00133     edgeVec.resize(newEnd-edgeVec.begin());
00134 }
00135 
00141 static void AllocateEdge(MeshType &m)
00142 {
00143   // Delete all the edges (if any)
00144   for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00145         tri::Allocator<MeshType>::DeleteEdge(m,*ei);
00146   tri::Allocator<MeshType>::CompactEdgeVector(m);
00147 
00148   // Compute and add edges
00149   std::vector<PEdge> Edges;
00150   FillUniqueEdgeVector(m,Edges);
00151   assert(m.edge.empty());
00152   tri::Allocator<MeshType>::AddEdges(m,Edges.size());
00153   assert(m.edge.size()==Edges.size());
00154 
00155   // Setup adjacency relations
00156   if(tri::HasEVAdjacency(m))
00157   {
00158     for(size_t i=0; i< Edges.size(); ++i)
00159     {
00160       m.edge[i].V(0) = Edges[i].v[0];
00161       m.edge[i].V(1) = Edges[i].v[1];
00162     }
00163   }
00164 
00165   if(tri::HasEFAdjacency(m)) // Note it is an unordered relation.
00166   {
00167     for(size_t i=0; i< Edges.size(); ++i)
00168     {
00169       std::vector<FacePointer> fpVec;
00170       std::vector<int> eiVec;
00171       face::EFStarFF(Edges[i].f,Edges[i].z,fpVec,eiVec);
00172       m.edge[i].EFp() = Edges[i].f;
00173       m.edge[i].EFi() = Edges[i].z;
00174     }
00175   }
00176 
00177   if(tri::HasFEAdjacency(m))
00178   {
00179     for(size_t i=0; i< Edges.size(); ++i)
00180     {
00181       std::vector<FacePointer> fpVec;
00182       std::vector<int> eiVec;
00183       face::EFStarFF(Edges[i].f,Edges[i].z,fpVec,eiVec);
00184       for(size_t j=0;j<fpVec.size();++j)
00185         fpVec[j]->FEp(eiVec[j])=&(m.edge[i]);
00186 
00187 //      Edges[i].f->FE(Edges[i].z) = &(m.edge[i]);
00188 //      Connect in loop the non manifold
00189 //      FaceType* fpit=fp;
00190 //      int eit=ei;
00191 
00192 //      do
00193 //      {
00194 //        faceVec.push_back(fpit);
00195 //        indVed.push_back(eit);
00196 //        FaceType *new_fpit = fpit->FFp(eit);
00197 //        int       new_eit  = fpit->FFi(eit);
00198 //        fpit=new_fpit;
00199 //        eit=new_eit;
00200 //      } while(fpit != fp);
00201 
00202 
00203 //      m.edge[i].EFp() = Edges[i].f;
00204 //      m.edge[i].EFi() = ;
00205     }
00206   }
00207 
00208 }
00209 
00212 static void ClearFaceFace(MeshType &m)
00213 {
00214   RequireFFAdjacency(m);
00215   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00216   {
00217     if( ! (*fi).IsD() )
00218     {
00219       for(int j=0;j<fi->VN();++j)
00220       {
00221         fi->FFp(j)=0;
00222         fi->FFi(j)=-1;
00223       }
00224     }
00225   }
00226 }
00227 
00229 static void FaceFace(MeshType &m)
00230 {
00231   RequireFFAdjacency(m);
00232   if( m.fn == 0 ) return;
00233 
00234   std::vector<PEdge> e;
00235   FillEdgeVector(m,e);
00236   sort(e.begin(), e.end());                                                     // Lo ordino per vertici
00237 
00238   int ne = 0;                                                                                   // Numero di edge reali
00239 
00240   typename std::vector<PEdge>::iterator pe,ps;
00241   ps = e.begin();pe=e.begin();
00242   //for(ps = e.begin(),pe=e.begin();pe<=e.end();++pe)   // Scansione vettore ausiliario
00243   do
00244   {
00245     if( pe==e.end() || !(*pe == *ps) )                                  // Trovo blocco di edge uguali
00246     {
00247       typename std::vector<PEdge>::iterator q,q_next;
00248       for (q=ps;q<pe-1;++q)                                             // Scansione facce associate
00249       {
00250         assert((*q).z>=0);
00251         //assert((*q).z< 3);
00252         q_next = q;
00253         ++q_next;
00254         assert((*q_next).z>=0);
00255         assert((*q_next).z< (*q_next).f->VN());
00256         (*q).f->FFp(q->z) = (*q_next).f;                                // Collegamento in lista delle facce
00257         (*q).f->FFi(q->z) = (*q_next).z;
00258       }
00259       assert((*q).z>=0);
00260       assert((*q).z< (*q).f->VN());
00261       (*q).f->FFp((*q).z) = ps->f;
00262       (*q).f->FFi((*q).z) = ps->z;
00263       ps = pe;
00264       ++ne;                                                                             // Aggiorno il numero di edge
00265     }
00266     if(pe==e.end()) break;
00267     ++pe;
00268   } while(true);
00269 }
00270 
00272 
00279 static void VertexFace(MeshType &m)
00280 {
00281   RequireVFAdjacency(m);
00282 
00283   for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00284   {
00285     (*vi).VFp() = 0;
00286     (*vi).VFi() = 0; // note that (0,-1) means uninitiazlied while 0,0 is the valid initialized values for isolated vertices.
00287   }
00288 
00289   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00290     if( ! (*fi).IsD() )
00291     {
00292       for(int j=0;j<(*fi).VN();++j)
00293       {
00294         (*fi).VFp(j) = (*fi).V(j)->VFp();
00295         (*fi).VFi(j) = (*fi).V(j)->VFi();
00296         (*fi).V(j)->VFp() = &(*fi);
00297         (*fi).V(j)->VFi() = j;
00298       }
00299     }
00300 }
00301 
00302 
00304 
00306 
00310 class PEdgeTex
00311 {
00312 public:
00313 
00314   typename FaceType::TexCoordType  v[2];                // the two TexCoord are ordered!
00315   FacePointer    f;                       // the face where this edge belong
00316   int      z;                                 // index in [0..2] of the edge of the face
00317 
00318   PEdgeTex() {}
00319 
00320   void Set( FacePointer  pf, const int nz )
00321   {
00322     assert(pf!=0);
00323     assert(nz>=0);
00324     assert(nz<3);
00325 
00326     v[0] = pf->WT(nz);
00327     v[1] = pf->WT(pf->Next(nz));
00328     assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
00329 
00330     if( v[1] < v[0] ) std::swap(v[0],v[1]);
00331     f    = pf;
00332     z    = nz;
00333   }
00334 
00335   inline bool operator <  ( const PEdgeTex & pe ) const
00336   {
00337     if( v[0]<pe.v[0] ) return true;
00338     else if( pe.v[0]<v[0] ) return false;
00339     else return v[1] < pe.v[1];
00340   }
00341   inline bool operator == ( const PEdgeTex & pe ) const
00342   {
00343     return (v[0]==pe.v[0]) && (v[1]==pe.v[1]);
00344   }
00345   inline bool operator != ( const PEdgeTex & pe ) const
00346   {
00347     return (v[0]!=pe.v[0]) || (v[1]!=pe.v[1]);
00348   }
00349 
00350 };
00351 
00352 
00354 
00360 static void FaceFaceFromTexCoord(MeshType &m)
00361 {
00362   RequireFFAdjacency(m);
00363   RequirePerFaceWedgeTexCoord(m);
00364   vcg::tri::UpdateTopology<MeshType>::FaceFace(m);
00365   for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
00366   {
00367     if (!(*fi).IsD())
00368     {
00369       for (int i = 0; i < (*fi).VN(); i++)
00370       {
00371         if (!vcg::face::IsBorder((*fi), i))
00372         {
00373           typename MeshType::FacePointer nextFace = (*fi).FFp(i);
00374           int nextEdgeIndex = (*fi).FFi(i);
00375           bool border = false;
00376           if ((*fi).cV(i) == nextFace->cV(nextEdgeIndex))
00377           {
00378             if ((*fi).WT(i) != nextFace->WT(nextEdgeIndex) || (*fi).WT((*fi).Next(i)) != nextFace->WT(nextFace->Next(nextEdgeIndex)))
00379               border = true;
00380           }
00381           else
00382           {
00383             if ((*fi).WT(i) != nextFace->WT(nextFace->Next(nextEdgeIndex)) || (*fi).WT((*fi).Next(i)) != nextFace->WT(nextEdgeIndex))
00384               border = true;
00385           }
00386           if (border)
00387             vcg::face::FFDetach((*fi), i);
00388 
00389         }
00390       }
00391     }
00392   }
00393 }
00394 
00396 static void TestVertexEdge(MeshType &m)
00397 {
00398   std::vector<int> numVertex(m.vert.size(),0);
00399   
00400   tri::RequireVEAdjacency(m);
00401   
00402   for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00403   {
00404       if (!(*ei).IsD())
00405       {
00406         assert(tri::IsValidPointer(m,ei->V(0)));
00407         assert(tri::IsValidPointer(m,ei->V(1)));
00408         if(ei->VEp(0)) assert(tri::IsValidPointer(m,ei->VEp(0)));
00409         if(ei->VEp(1)) assert(tri::IsValidPointer(m,ei->VEp(1)));
00410         numVertex[tri::Index(m,(*ei).V(0))]++;
00411         numVertex[tri::Index(m,(*ei).V(1))]++;
00412       }
00413   }
00414   
00415   for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00416   {
00417       if (!vi->IsD())
00418       {
00419         int cnt =0;
00420         int ind = tri::Index(m,*vi);
00421         int incidentNum = numVertex[ind];
00422         for(edge::VEIterator<EdgeType> vei(&*vi);!vei.End();++vei)
00423           cnt++;
00424         EdgeType *vep = vi->VEp();
00425         assert((incidentNum==0) == (vi->VEp()==0) );
00426         assert(cnt==incidentNum);        
00427       }
00428   }  
00429 }
00430 
00431 
00433 static void TestVertexFace(MeshType &m)
00434 {
00435     SimpleTempData<typename MeshType::VertContainer, int > numVertex(m.vert,0);
00436 
00437   assert(tri::HasPerVertexVFAdjacency(m));
00438 
00439     for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00440     {
00441         if (!(*fi).IsD())
00442         {
00443             numVertex[(*fi).V0(0)]++;
00444             numVertex[(*fi).V1(0)]++;
00445             numVertex[(*fi).V2(0)]++;
00446         }
00447     }
00448 
00449     vcg::face::VFIterator<FaceType> VFi;
00450 
00451     for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00452     {
00453         if (!vi->IsD())
00454         if(vi->VFp()!=0) // unreferenced vertices MUST have VF == 0;
00455         {
00456             int num=0;
00457             assert(tri::IsValidPointer(vi->VFp()));
00458             VFi.f=vi->VFp();
00459             VFi.z=vi->VFi();
00460             while (!VFi.End())
00461             {
00462                 num++;
00463                 assert(!VFi.F()->IsD());
00464                 assert((VFi.F()->V(VFi.I()))==&(*vi));
00465                 ++VFi;
00466             }
00467             assert(num==numVertex[&(*vi)]);
00468         }
00469     }
00470 }
00471 
00473 static void TestFaceFace(MeshType &m)
00474 {
00475   assert(HasFFAdjacency(m));
00476 
00477   for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
00478     {
00479     if (!fi->IsD())
00480         {
00481       for (int i=0;i<(*fi).VN();i++)
00482             {
00483         FaceType *ffpi=fi->FFp(i);
00484         int e=fi->FFi(i);
00485         //invariant property of FF topology for two manifold meshes
00486         assert(ffpi->FFp(e) == &(*fi));
00487         assert(ffpi->FFi(e) == i);
00488 
00489         // Test that the two faces shares the same edge
00490         // Vertices of the i-th edges of the first face
00491         VertexPointer v0i= fi->V0(i);
00492         VertexPointer v1i= fi->V1(i);
00493         // Vertices of the corresponding edge on the other face
00494         VertexPointer ffv0i= ffpi->V0(e);
00495         VertexPointer ffv1i= ffpi->V1(e);
00496 
00497         assert( (ffv0i==v0i) || (ffv0i==v1i) );
00498         assert( (ffv1i==v0i) || (ffv1i==v1i) );
00499             }
00500 
00501         }
00502     }
00503 }
00504 
00507 class PVertexEdge
00508 {
00509 public:
00510 
00511   VertexPointer  v;             // the two Vertex pointer are ordered!
00512   EdgePointer    e;               // the edge where this vertex belong
00513   int      z;                                 // index in [0..1] of the vertex of the edge
00514 
00515   PVertexEdge(  ) {}
00516   PVertexEdge( EdgePointer  pe, const int nz )
00517 {
00518   assert(pe!=0);
00519   assert(nz>=0);
00520   assert(nz<2);
00521 
00522   v= pe->V(nz);
00523   e    = pe;
00524   z    = nz;
00525 }
00526 inline bool operator  <  ( const PVertexEdge & pe ) const { return ( v<pe.v ); }
00527 inline bool operator ==  ( const PVertexEdge & pe ) const { return ( v==pe.v ); }
00528 inline bool operator !=  ( const PVertexEdge & pe ) const { return ( v!=pe.v ); }
00529 };
00530 
00531 
00532 
00533 static void EdgeEdge(MeshType &m)
00534 {
00535   RequireEEAdjacency(m);
00536   std::vector<PVertexEdge> v;
00537   if( m.en == 0 ) return;
00538 
00539 //  printf("Inserting Edges\n");
00540   for(EdgeIterator pf=m.edge.begin(); pf!=m.edge.end(); ++pf)                   // Lo riempio con i dati delle facce
00541     if( ! (*pf).IsD() )
00542       for(int j=0;j<2;++j)
00543       {
00544 //        printf("egde %i ind %i (%i %i)\n",tri::Index(m,&*pf),j,tri::Index(m,pf->V(0)),tri::Index(m,pf->V(1)));
00545         v.push_back(PVertexEdge(&*pf,j));
00546       }
00547 
00548 //  printf("en = %i (%i)\n",m.en,m.edge.size());
00549   sort(v.begin(), v.end());                                                     // Lo ordino per vertici
00550 
00551   int ne = 0;                                                                                   // Numero di edge reali
00552 
00553   typename std::vector<PVertexEdge>::iterator pe,ps;
00554   // for(ps = v.begin(),pe=v.begin();pe<=v.end();++pe)  // Scansione vettore ausiliario
00555   ps = v.begin();pe=v.begin();
00556   do
00557   {
00558 //    printf("v %i -> e %i\n",tri::Index(m,(*ps).v),tri::Index(m,(*ps).e));
00559     if( pe==v.end() || !(*pe == *ps) )                                  // Trovo blocco di edge uguali
00560     {
00561       typename std::vector<PVertexEdge>::iterator q,q_next;
00562       for (q=ps;q<pe-1;++q)                                             // Scansione edge associati
00563       {
00564         assert((*q).z>=0);
00565         assert((*q).z< 2);
00566         q_next = q;
00567         ++q_next;
00568         assert((*q_next).z>=0);
00569         assert((*q_next).z< 2);
00570         (*q).e->EEp(q->z) = (*q_next).e;                                // Collegamento in lista delle facce
00571         (*q).e->EEi(q->z) = (*q_next).z;
00572       }
00573       assert((*q).z>=0);
00574       assert((*q).z< 2);
00575       (*q).e->EEp((*q).z) = ps->e;
00576       (*q).e->EEi((*q).z) = ps->z;
00577       ps = pe;
00578       ++ne;                                                                             // Aggiorno il numero di edge
00579     }
00580     if(pe==v.end()) break;
00581     ++pe;
00582    } while(true);
00583 }
00584 
00585 static void VertexEdge(MeshType &m)
00586 {
00587   RequireVEAdjacency(m);
00588 
00589   for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
00590   {
00591     (*vi).VEp() = 0;
00592     (*vi).VEi() = 0;
00593   }
00594 
00595   for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
00596   if( ! (*ei).IsD() )
00597   {
00598     for(int j=0;j<2;++j)
00599     { assert(tri::IsValidPointer(m,ei->V(j)));
00600       (*ei).VEp(j) = (*ei).V(j)->VEp();
00601       (*ei).VEi(j) = (*ei).V(j)->VEi();
00602       (*ei).V(j)->VEp() = &(*ei);
00603       (*ei).V(j)->VEi() = j;
00604     }
00605   }
00606 }
00607 
00608 }; // end class
00609 
00610 }       // End namespace
00611 }       // End namespace
00612 
00613 
00614 #endif


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