halfedge_indexed.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 __VCGLIB_HALFEDGE_
00025 #define __VCGLIB_HALFEDGE_
00026 
00027 #include <vcg/complex/algorithms/clean.h>
00028 #include <vcg/complex/algorithms/update/topology.h>
00029 #include <vcg/complex/algorithms/update/halfedge_topology.h>
00030 
00031 namespace vcg
00032 {
00033     namespace tri{
00036 
00039         template <class MeshType  >
00040                 class UpdateHalfEdges{
00041                 public:
00042             typedef typename MeshType::VertexType VertexType;
00043             typedef typename MeshType::VertexPointer VertexPointer;
00044             typedef typename MeshType::VertexIterator VertexIterator;
00045             typedef typename MeshType::HEdgePointer HEdgePointer;
00046             typedef typename MeshType::HEdgeType HEdgeType;
00047             typedef typename MeshType::EdgePointer EdgePointer;
00048             typedef typename MeshType::EdgeType EdgeType;
00049             typedef typename MeshType::EdgeIterator EdgeIterator;
00050             typedef typename MeshType::HEdgeIterator HEdgeIterator;
00051             typedef typename MeshType::FaceIterator FaceIterator;
00052             typedef typename MeshType::FaceType FaceType;
00053 
00054             struct VertexPairEdgePtr{
00055                 VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,HEdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){if(v0>v1) std::swap(v0,v1);}
00056                 bool operator <(const VertexPairEdgePtr &o) const {return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);}
00057                 bool operator ==(const VertexPairEdgePtr &o) const {return (v0 == o.v0)&& (v1==o.v1);}
00058 
00059                 VertexPointer v0,v1;
00060                 HEdgePointer ep;
00061             };
00062             struct FacePtrInt{
00063                 FacePtrInt ( FaceType * _f,int _i):f(_f),i(_i){}
00064                 FaceType * f;
00065                 int i;
00066             };
00067 
00068             typedef std::vector<bool> BitVector;
00069 
00075             static void FromIndexed(MeshType & m){
00076                 assert(HasFVAdjacency(m));
00077                 assert(HasHOppAdjacency(m));
00078                 assert(HasHNextAdjacency(m));
00079 
00080                 typename MeshType::template PerFaceAttributeHandle<BitVector> flagVisited =
00081                         vcg::tri::Allocator<MeshType>::template AddPerFaceAttribute<BitVector>(m,"");
00082                 std::vector<FacePtrInt > borderEdges;
00083 
00084                 // allocate all new half edges
00085                 FaceIterator fi;
00086                 unsigned int n_edges = 0;
00087 
00088                 // count how many half edge to allocate
00089                 for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD())
00090                 {n_edges+=(*fi).VN();
00091                     for(int i = 0; i < (*fi).VN(); ++i)
00092                         if(vcg::face::IsBorder<FaceType>((*fi),(i)))
00093                             ++n_edges;
00094                 }
00095 
00096                 m.hedge.clear();
00097                 m.hn = 0;
00098 
00099                 // allocate the half edges
00100                 typename MeshType::HEdgeIterator ei = vcg::tri::Allocator<MeshType>::AddHEdges(m,n_edges);
00101 
00102 
00103                 std::vector<VertexPairEdgePtr> all;
00104                 int firstEdge = 0;
00105                 for(fi = m.face.begin(); fi != m.face.end(); ++fi)if(!(*fi).IsD()){
00106                     assert((*fi).VN()>2);
00107                     if(flagVisited[*fi].empty()) {flagVisited[*fi].resize((*fi).VN());}
00108 
00109                     for(int i  = 0; i < (*fi).VN(); ++i,++ei)
00110                     {
00111                         (*ei).HVp() = (*fi).V(i);
00112                         (*ei).HNp() = &m.hedge[firstEdge + (i +1) % (*fi).VN()];
00113                         if(MeshType::HEdgeType::HasHFAdjacency())
00114                             (*ei).HFp() = &(*fi);
00115                         if( MeshType::FaceType::HasFHAdjacency())
00116                             (*fi).FHp() = &(*ei);
00117                         if(MeshType::HEdgeType::HasHPrevAdjacency())
00118                             (*ei).HPp() = &m.hedge[firstEdge + (i +(*fi).VN()-1) % (*fi).VN()];
00119                         if(HasVHAdjacency(m))
00120                             (*ei).HVp()->VHp() = &(*ei);
00121                         all.push_back(VertexPairEdgePtr((*fi).V(i), (*fi).V((*fi).Next(i)),&(*ei)));// it will be used to link the hedges
00122 
00123                         if(  vcg::face::IsBorder<FaceType>((*fi),(i)))
00124                             borderEdges.push_back(FacePtrInt(&(*fi),i));
00125                     }
00126                     firstEdge += (*fi).VN();
00127                 }
00128 
00129                 // add all the border hedges
00130                 int borderLength;
00131                 typename std::vector<FacePtrInt >::iterator ebi;
00132                 for( ebi = borderEdges.begin(); ebi != borderEdges.end(); ++ebi)
00133                     if( !flagVisited[(*ebi).f][(*ebi).i])// not already inserted
00134                     {
00135 
00136                         borderLength = 0;
00137                         vcg::face::Pos<FaceType> bp((*ebi).f,(*ebi).i);
00138 
00139                         //FaceType * start = (*ebi).f;
00140                         VertexType * start = ((*ebi).f)->V((*ebi).i);
00141                         do{
00142                             all.push_back( VertexPairEdgePtr ( bp.f->V( bp.f->Next(bp.z) ),bp.f->V( bp.z ),&(*ei)));
00143                             (*ei).HVp() =  bp.f->V(bp.f->Next(bp.z)) ;
00144                             flagVisited[bp.f][bp.z] = true;
00145                             ++ei;
00146                             bp.NextB();
00147                             ++borderLength;
00148                         }while (bp.v != start);
00149                         //}while (bp.f != start);
00150 
00151 
00152                         // run over the border edges to link the adjacencies
00153                         for(int be = 0; be < borderLength; ++be)
00154                         {
00155                             if(MeshType::HEdgeType::HasHFAdjacency())
00156                                 m.hedge[firstEdge + be].HFp() = NULL;
00157 
00158                             if(MeshType::HEdgeType::HasHPrevAdjacency())
00159                                 m.hedge[firstEdge + be].HPp() = &m.hedge[firstEdge + (be +borderLength-1) % borderLength];
00160 
00161                             m.hedge[firstEdge + be].HNp() = &m.hedge[firstEdge + (be +1) % borderLength];
00162                         }
00163                         firstEdge+=borderLength;
00164                     }
00165 
00166                 vcg::tri::Allocator<MeshType>:: template DeletePerFaceAttribute<BitVector>(m,flagVisited );
00167 
00168                 std::sort(all.begin(),all.end());
00169                 assert(all.size() == n_edges);
00170 
00171                 for(unsigned int i = 0 ; i < all.size(); )
00172                     if(all[i]  == all[i+1])
00173                     {
00174                         all[i].ep->HOp()        = all[i+1].ep;
00175                         all[i+1].ep->HOp() = all[i].ep;
00176                         i+=2;
00177                     }
00178                     else
00179                     {
00180                         all[i].ep->HOp() = all[i].ep;
00181                         i+=1;
00182                     }
00183 
00184                 if(HasEHAdjacency(m) && HasHEAdjacency(m))
00185                 {
00186                     assert(m.edge.size() == 0 || m.edge.size() == n_edges/2);
00187 
00188                     if ( m.edge.size() == 0 )
00189                     {
00190                         m.en = 0;
00191                         // allocate the edges
00192                         typename MeshType::EdgeIterator edge_i = vcg::tri::Allocator<MeshType>::AddEdges(m,n_edges/2);
00193 
00194                         for(ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
00195                         {
00196                             if((*ei).HEp() == NULL)
00197                             {
00198                                 (*ei).HEp() = &(*edge_i);
00199                                 (*ei).HOp()->HEp() = &(*edge_i);
00200 
00201                                 (*edge_i).EHp() = &(*ei);
00202 
00203                                 ++edge_i;
00204                             }
00205                         }
00206 
00207                     }
00208                     else
00209                     {
00210 
00211                         if(HasEVAdjacency(m) && HasHEAdjacency(m) && HasEHAdjacency(m))
00212                         {
00213                             //update edge relations
00214 
00215                             for(typename MeshType::EdgeIterator ei1 = m.edge.begin(); ei1 != m.edge.end(); ++ei1 )
00216                             {
00217                                 vector<HEdgePointer> hedges = HalfEdgeTopology<MeshType>::get_incident_hedges((*ei1).V(0));
00218 
00219                                 for(typename vector<HEdgePointer>::iterator hi = hedges.begin(); hi != hedges.end(); ++hi)
00220                                 {
00221                                     if((*hi)->HOp()->HVp() == (*ei1).V(1))
00222                                     {
00223 
00224                                         assert((*hi)->HEp() == NULL);
00225                                         assert((*hi)->HOp()->HEp() == NULL);
00226 
00227                                         // EH
00228                                         (*ei1).EHp() = *hi;
00229 
00230                                         // HE
00231                                         (*hi)->HEp() = &(*ei1);
00232                                         (*hi)->HOp()->HEp() = &(*ei1);
00233 
00234                                         break;
00235                                     }
00236                                 }
00237                             }
00238                         }
00239                     }
00240 
00241                 }
00242 
00243             }
00244 
00248             static bool CheckConsistency_FHp(MeshType &  m){
00249                 assert(MeshType::FaceType::HasFHAdjacency());
00250                 FaceIterator fi;
00251                 for(fi = m.face.begin(); fi != m.face.end(); ++fi)
00252                     if(!(*fi).IsD()){
00253                     if((*fi).FHp() <  &(*m.hedge.begin())) return false;
00254                     if((*fi).FHp() >  &(m.hedge.back())) return false;
00255                 }
00256                 return true;
00257             }
00258 
00262             static bool CheckConsistency(MeshType & m){
00263                 assert(MeshType::HEdgeType::HasHNextAdjacency());
00264                 assert(MeshType::HEdgeType::HasHOppAdjacency());
00265                 assert(MeshType::HEdgeType::HasHVAdjacency());
00266                 assert(MeshType::FaceType::HasFHAdjacency());
00267 
00268                 //bool hasHEF = ( MeshType::HEdgeType::HasHFAdjacency());
00269                 bool hasHP = ( MeshType::HEdgeType::HasHPrevAdjacency());
00270 
00271                 FaceIterator fi;
00272                 HEdgePointer ep,ep1;
00273                 int cnt = 0;
00274 
00275                 if( MeshType::HEdgeType::HasHFAdjacency() )
00276                 {
00277                     int iDb = 0;
00278                     for(fi = m.face.begin(); fi != m.face.end(); ++fi,++iDb)
00279                         if(!(*fi).IsD())
00280                         {
00281                         ep = ep1 = (*fi).FHp();
00282 
00283                         do{
00284                             if(ep->IsD())
00285                                 return false; // the hedge should not be connected, it has been deleted
00286                             if( ! ep->HFp())
00287                                 return false;
00288                             if(ep->HFp() != &(*fi))
00289                                 return false;// hedge is not pointing to the rigth face
00290                             ep = ep->HNp();
00291                             if(cnt++ > m.hn)
00292                                 return false; // hedges are ill connected (HENp())
00293 
00294                         }while(ep!=ep1);
00295 
00296                     }
00297                 }
00298 
00299                 HEdgePointer epPrev;
00300                 HEdgeIterator hi;
00301                 //bool extEdge ;
00302                 for( hi  = m.hedge.begin(); hi != m.hedge.end(); ++hi)
00303                     if(!(*hi).IsD())
00304                     {
00305                         //cnt = 0;
00306                         epPrev = ep = ep1 = &(*hi);
00307                         //do{
00308                         //extEdge = (ep->HFp()==NULL);
00309                         if(hasHP)
00310                         {
00311                             if( !ep->HPp())
00312                                 return false;
00313                             if( ep->HPp() == ep)
00314                                 return false; // the previous of an edge cannot be the edge itself
00315                             if( ep->HNp()->HPp() != ep)
00316                                 return false; // next and prev relation are not mutual
00317                             if( ep->HPp()->IsD())
00318                                 return false; //
00319                         }
00320 
00321                         if( ! ep->HOp() )
00322                             return false;
00323 
00324                         if( ep->HOp()  == ep)
00325                             return false; // opposite relation is not mutual
00326 
00327                         if( ep->HOp()->IsD())
00328                             return false;
00329 
00330                         if( ep->HOp()->HOp() != ep)
00331                             return false; // opposite relation is not mutual
00332 
00333                         if( HasHFAdjacency(m) )
00334                         {
00335                             if(ep->HFp())
00336                             {
00337                                 if( ep->HFp()->IsD())
00338                                     return false; // pointed face must not be deleted
00339                             }
00340                         }
00341 
00342                                                 if( HasHEAdjacency(m) && (m.en!=0))
00343                         {
00344                             if( ! ep->HEp())
00345                                 return false; //halfedge must point to an edge
00346 
00347                             if( ep->HEp()->IsD())
00348                                 return false; // pointed edge must not be deleted
00349 
00350                             if(ep->HEp() != ep->HOp()->HEp())
00351                                 return false;   // he and opposite he must point to the same edge
00352 
00353                             if(ep->HEp()->EHp() != ep && ep->HEp()->EHp() != ep->HOp() )
00354                                 return false;   // halfedge points to an edge not pointing it or its opposite
00355 
00356                         }
00357 
00358 
00359                         if( !ep->HNp() )
00360                             return false;
00361 
00362                         if( ep->HNp() == ep )
00363                             return false; //  the next of an hedge cannot be the hedge itself
00364 
00365                         if( ep->HNp()->IsD())
00366                             return false; //
00367 
00368                                                 if(hasHP)
00369                         if( ep->HNp()->HPp() != ep)
00370                             return false; //
00371 
00372                         if( HasHVAdjacency(m) )
00373                         {
00374                             if( ! ep->HVp() )
00375                                 return false; // halfedge must point to a vertex
00376 
00377                             if( ep->HVp()->IsD() )
00378                                 return false; // pointed vertex must not be deleted
00379 
00380                             if( HasVHAdjacency(m) )
00381                                 if( ! (ep->HVp()->VHp()) )
00382                                     return false; //  halfedge points to a vertex pointing NULL
00383 
00384                         }
00385 
00386 
00387                         ep = ep->HNp();
00388                         if( ep->HVp() != epPrev->HOp()->HVp())
00389                             return false;
00390 
00391                         epPrev = ep;
00392 
00393                         // if(cnt++ > m.hn)
00394                         //     return false; // edges are ill connected (HENp())
00395 
00396                         //}while(ep!=ep1);
00397                     }
00398 
00399                 if(HasEHAdjacency(m) && HasHEAdjacency(m))
00400                     for(EdgeIterator ei  = m.edge.begin(); ei != m.edge.end(); ++ei)
00401                     {
00402                         if(!(*ei).IsD())
00403                         {
00404                             if( !(*ei).EHp())
00405                                 return false;   //edge must have a valid pointer to his halfedge
00406 
00407                             if( (*ei).EHp()->HEp() !=  &(*ei) )
00408                                 return false; // edge's halfedge must point to the edge itself
00409 
00410                             if( (*ei).EHp()->IsD())
00411                                 return false;
00412                         }
00413                     }
00414 
00415                 if(HasVHAdjacency(m))
00416                     for(VertexIterator vi  = m.vert.begin(); vi != m.vert.end(); ++vi)
00417                     {
00418                         if( !(*vi).IsD() )
00419                             if( (*vi).VHp() )
00420                             {
00421                                 if( (*vi).VHp()->HVp() !=  &(*vi) )
00422                                     return false;
00423                                 if( (*vi).VHp()->IsD())
00424                                     return false;
00425                             }
00426                     }
00427 
00428 
00429                 return true;
00430             }
00431 
00434         private:
00435             static void SetRelationsLoopFace(HEdgeType * e0, FaceType * f){
00436                 assert(HEdgeType::HasHNextAdjacency());
00437                 assert(FaceType::HasFHAdjacency());
00438 
00439                 HEdgeType *e = e0;
00440                 assert(e!=NULL);
00441                 do{ e->HFp() = f; e = e->HNp(); } while(e != e0);
00442                 f->FHp() = e0;
00443             }
00444 
00448             static void MergeFaces(FaceType *, FaceType *){}
00449 
00453             static HEdgeType *  PreviousEdge(HEdgeType * e0){
00454                 HEdgeType *  ep = e0;
00455                 do{
00456                     if(ep->HNp() == e0) return ep;
00457                     ep = ep->HNp();
00458                 }while(ep!=e0);
00459                 assert(0); // degenerate loop
00460                 return 0;
00461             }
00462 
00463         public:
00474             static void AddHEdge(MeshType &m, HEdgeType * e0, HEdgeType * e1){
00475                 assert(e1!=e0->HNp());
00476                 assert(e0!=e1->HNp());
00477                 bool hasP =  MeshType::HEdgeType::HasHPrevAdjacency();
00478                 assert(e0->HOp() != e1); // the hedge already exists
00479                 assert(e0!=e1->HNp());
00480 
00481                 std::vector<typename MeshType::HEdgePointer* > toUpdate;
00482                 toUpdate.push_back(&e0);
00483                 toUpdate.push_back(&e1);
00484                 HEdgeIterator ei0  = vcg::tri::Allocator<MeshType>::AddHEdges(m,2,toUpdate);
00485 
00486                 HEdgeIterator ei1 = ei0; ++ei1;
00487                 (*ei0).HNp() = e1;(*ei0).HVp() = e0->HVp();
00488                 (*ei1).HNp() = e0;(*ei1).HVp() = e1->HVp();
00489 
00490                 HEdgePointer e0_HEPp = 0,e1_HEPp = 0,ep =0;
00491                 if(hasP){
00492                     e0_HEPp = e0->HPp();
00493                     e1_HEPp = e1->HPp();
00494                 }else{// does not have pointer to previous, it must be computed
00495                     ep = e0;
00496                     do{
00497                         if(ep->HNp() == e0) e0_HEPp = ep;
00498                         if(ep->HNp() == e1) e1_HEPp = ep;
00499                         ep = ep->HNp();
00500                     }while(ep!=e0);
00501                 }
00502                 if(hasP){
00503                     (*ei0).HPp() = e0->HPp();
00504                     (*ei1).HPp() = e1->HPp();
00505                     e0->HPp() = &(*ei1);
00506                     e1->HPp() = &(*ei0);
00507                 }
00508                 e0_HEPp -> HNp() = &(*ei0);
00509                 e1_HEPp -> HNp() = &(*ei1);
00510 
00511                 (*ei0).HOp() = &(*ei1);
00512                 (*ei1).HOp() = &(*ei0);
00513 
00514 
00515                 if( HEdgeType::HasHFAdjacency() && FaceType::HasFHAdjacency()){
00516                     FaceIterator fi0  = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
00517                     m.face.back().ImportData(*e0->HFp());
00518 
00519                     SetRelationsLoopFace(&(*ei0),e1->HFp());            // one loop to the old face
00520                     SetRelationsLoopFace(&(*ei1),&m.face.back());       // the other  to the new face
00521                 }
00522             }
00523 
00534             static void RemoveHEdge(MeshType &m, HEdgeType * e){
00535                 assert(MeshType::HEdgeType::HasHNextAdjacency());
00536                 assert(MeshType::HEdgeType::HasHOppAdjacency());
00537                 assert(MeshType::FaceType::HasFHAdjacency());
00538 
00539                 bool hasP =  MeshType::HEdgeType::HasHPrevAdjacency();
00540                 HEdgePointer e_HEPp,eO_HEPp;
00541 
00542                 if(hasP){
00543                     e_HEPp = e->HPp();
00544                     eO_HEPp = e->HOp()->HPp();
00545                 }else{
00546                     e_HEPp = PreviousEdge(e);
00547                     eO_HEPp = PreviousEdge(e->HOp());
00548                 }
00549 
00550                 assert(e_HEPp->HNp() == e);
00551                 assert(eO_HEPp->HNp() == e->HOp());
00552                 e_HEPp->HNp() = e->HOp()->HNp();
00553                 eO_HEPp->HNp() = e-> HNp();
00554 
00555                 if(hasP) {
00556                     e->HOp()->HNp()->HPp() = e_HEPp;
00557                     e->HNp()->HPp() = eO_HEPp;
00558 
00559                     e->HPp() = NULL;
00560                     e-> HOp()->HPp() = NULL;
00561                 }
00562 
00563 
00564                 // take care of the faces
00565                 if(MeshType::HEdgeType::HasHFAdjacency()){
00566                     MergeFaces(e_HEPp->HFp(),eO_HEPp->HFp());
00567                     vcg::tri::Allocator<MeshType>::DeleteFace(m,*eO_HEPp->HFp());
00568                     SetRelationsLoopFace(e_HEPp,e_HEPp->HFp());
00569 
00570                 }
00571                 vcg::tri::Allocator<MeshType>::DeleteHEdge(m,*e->HOp());
00572                 vcg::tri::Allocator<MeshType>::DeleteHEdge(m,*e);
00573 
00574             }
00575 
00576         };// end class
00577         template <class MeshType  >
00578                 struct UpdateIndexed{
00579             typedef typename MeshType::VertexType VertexType;
00580             typedef typename MeshType::VertexPointer VertexPointer;
00581             typedef typename MeshType::HEdgePointer HEdgePointer;
00582             typedef typename MeshType::HEdgeType HEdgeType;
00583             typedef typename MeshType::HEdgeIterator HEdgeIterator;
00584             typedef typename MeshType::FaceIterator FaceIterator;
00585             typedef typename MeshType::FaceType FaceType;
00586 
00587             struct VertexPairEdgePtr{
00588                 VertexPairEdgePtr(VertexPointer _v0,VertexPointer _v1,HEdgePointer _ep):v0(_v0),v1(_v1),ep(_ep){if(v0>v1) std::swap(v0,v1);}
00589                 bool operator <(const VertexPairEdgePtr &o) const {return (v0 == o.v0)? (v1<o.v1):(v0<o.v0);}
00590                 bool operator ==(const VertexPairEdgePtr &o) const {return (v0 == o.v0)&& (v1==o.v1);}
00591 
00592                 VertexPointer v0,v1;
00593                 HEdgePointer ep;
00594             };
00595 
00602             static void FromHalfEdges(  MeshType & m ){
00603                 assert(HasFVAdjacency(m));
00604                 assert(MeshType::HEdgeType::HasHNextAdjacency());
00605                 assert(MeshType::HEdgeType::HasHVAdjacency());
00606                 assert(MeshType::HEdgeType::HasHOppAdjacency());
00607                 assert(MeshType::FaceType::HasFHAdjacency());
00608                 bool hasHEF;
00609                 //bool createFace,hasHEF,hasFHE;
00610 
00611                 //                              typename MeshType::template PerHEdgeAttributeHandle<bool> hV = Allocator<MeshType>::template AddPerHEdgeAttribute<bool>(m,"");
00612 
00613 
00614                 typename MeshType::HEdgeIterator ei;
00615                 typename MeshType::FacePointer fp;
00616                 typename MeshType::FaceIterator fi;
00617                 typename MeshType::HEdgePointer ep,epF;
00618                 //int vi = 0;
00619                 vcg::SimpleTempData<typename MeshType::HEdgeContainer,bool> hV(m.hedge);
00620 
00621                 hasHEF = (MeshType::HEdgeType::HasHFAdjacency());
00622                 assert( !hasHEF || (hasHEF && m.fn>0));
00623 
00624                 // if the edgetype has the pointer to face
00625                 // it is assumed the the edget2face pointer (HEFp) are correct
00626                 // and the faces are allocated
00627                 for ( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
00628                     if(!(*ei).IsD())                                                            // it has not been deleted
00629                         if(!hasHEF || ( hasHEF &&  (*ei).HFp()!=NULL))  // if it has a pointer to the face it is
00630                             // not null (i.e. it is not a border edge)
00631                             if(!hV[(*ei)] )                                                                     // it has not be visited yet
00632                             {
00633                     if(!hasHEF)// if it has
00634                         fp = &(* Allocator<MeshType>::AddFaces(m,1));
00635                     else
00636                         fp = (*ei).HFp();
00637 
00638                     ep = epF = &(*ei);
00639                     std::vector<VertexPointer> vpts;
00640                     do{vpts.push_back((*ep).HVp()); ep=ep->HNp();}while(ep!=epF);
00641                     //int idbg  =fp->VN();
00642                     if(size_t(fp->VN()) != vpts.size()){
00643                         fp->Dealloc();
00644                         fp ->Alloc(vpts.size());
00645                     }
00646                     //int idbg1  =fp->VN();
00647                     for(size_t i  = 0; i < vpts.size();++i) fp ->V(i) = vpts[i];// set the pointer from face to vertex
00648 
00649                     hV[(*ei)] = true;
00650                 }
00651                 //Allocator<MeshType>::DeletePerHEdgeAttribute(m,hV);
00652             }
00653 
00654         };
00655     } // end namespace vcg
00656 }
00657 #endif // __VCGLIB_EDGE_SUPPORT


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