00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00085 FaceIterator fi;
00086 unsigned int n_edges = 0;
00087
00088
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
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)));
00122
00123 if( vcg::face::IsBorder<FaceType>((*fi),(i)))
00124 borderEdges.push_back(FacePtrInt(&(*fi),i));
00125 }
00126 firstEdge += (*fi).VN();
00127 }
00128
00129
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])
00134 {
00135
00136 borderLength = 0;
00137 vcg::face::Pos<FaceType> bp((*ebi).f,(*ebi).i);
00138
00139
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
00150
00151
00152
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
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
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
00228 (*ei1).EHp() = *hi;
00229
00230
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
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;
00286 if( ! ep->HFp())
00287 return false;
00288 if(ep->HFp() != &(*fi))
00289 return false;
00290 ep = ep->HNp();
00291 if(cnt++ > m.hn)
00292 return false;
00293
00294 }while(ep!=ep1);
00295
00296 }
00297 }
00298
00299 HEdgePointer epPrev;
00300 HEdgeIterator hi;
00301
00302 for( hi = m.hedge.begin(); hi != m.hedge.end(); ++hi)
00303 if(!(*hi).IsD())
00304 {
00305
00306 epPrev = ep = ep1 = &(*hi);
00307
00308
00309 if(hasHP)
00310 {
00311 if( !ep->HPp())
00312 return false;
00313 if( ep->HPp() == ep)
00314 return false;
00315 if( ep->HNp()->HPp() != ep)
00316 return false;
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;
00326
00327 if( ep->HOp()->IsD())
00328 return false;
00329
00330 if( ep->HOp()->HOp() != ep)
00331 return false;
00332
00333 if( HasHFAdjacency(m) )
00334 {
00335 if(ep->HFp())
00336 {
00337 if( ep->HFp()->IsD())
00338 return false;
00339 }
00340 }
00341
00342 if( HasHEAdjacency(m) && (m.en!=0))
00343 {
00344 if( ! ep->HEp())
00345 return false;
00346
00347 if( ep->HEp()->IsD())
00348 return false;
00349
00350 if(ep->HEp() != ep->HOp()->HEp())
00351 return false;
00352
00353 if(ep->HEp()->EHp() != ep && ep->HEp()->EHp() != ep->HOp() )
00354 return false;
00355
00356 }
00357
00358
00359 if( !ep->HNp() )
00360 return false;
00361
00362 if( ep->HNp() == ep )
00363 return false;
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;
00376
00377 if( ep->HVp()->IsD() )
00378 return false;
00379
00380 if( HasVHAdjacency(m) )
00381 if( ! (ep->HVp()->VHp()) )
00382 return false;
00383
00384 }
00385
00386
00387 ep = ep->HNp();
00388 if( ep->HVp() != epPrev->HOp()->HVp())
00389 return false;
00390
00391 epPrev = ep;
00392
00393
00394
00395
00396
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;
00406
00407 if( (*ei).EHp()->HEp() != &(*ei) )
00408 return false;
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);
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);
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{
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());
00520 SetRelationsLoopFace(&(*ei1),&m.face.back());
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
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 };
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
00610
00611
00612
00613
00614 typename MeshType::HEdgeIterator ei;
00615 typename MeshType::FacePointer fp;
00616 typename MeshType::FaceIterator fi;
00617 typename MeshType::HEdgePointer ep,epF;
00618
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
00625
00626
00627 for ( ei = m.hedge.begin(); ei != m.hedge.end(); ++ei)
00628 if(!(*ei).IsD())
00629 if(!hasHEF || ( hasHEF && (*ei).HFp()!=NULL))
00630
00631 if(!hV[(*ei)] )
00632 {
00633 if(!hasHEF)
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
00642 if(size_t(fp->VN()) != vpts.size()){
00643 fp->Dealloc();
00644 fp ->Alloc(vpts.size());
00645 }
00646
00647 for(size_t i = 0; i < vpts.size();++i) fp ->V(i) = vpts[i];
00648
00649 hV[(*ei)] = true;
00650 }
00651
00652 }
00653
00654 };
00655 }
00656 }
00657 #endif // __VCGLIB_EDGE_SUPPORT