From 1509a9b43410fcb5b9afdf2fab2e92b33304c4df Mon Sep 17 00:00:00 2001 From: cignoni <paolo.cignoni@isti.cnr.it> Date: Wed, 19 Jan 2005 10:35:28 +0000 Subject: [PATCH] Better management of symmetric/asymmetric edge collapses --- .../local_optimization/tri_edge_collapse.h | 12 +- .../tri_edge_collapse_quadric.h | 130 ++++++++++-------- 2 files changed, 80 insertions(+), 62 deletions(-) diff --git a/vcg/complex/local_optimization/tri_edge_collapse.h b/vcg/complex/local_optimization/tri_edge_collapse.h index 62431c0f..d170a1da 100644 --- a/vcg/complex/local_optimization/tri_edge_collapse.h +++ b/vcg/complex/local_optimization/tri_edge_collapse.h @@ -22,6 +22,9 @@ ****************************************************************************/ /**************************************************************************** $Log: not supported by cvs2svn $ + Revision 1.15 2004/12/10 01:03:53 cignoni + better comments and removed logging + Revision 1.14 2004/11/23 10:34:23 cignoni passed parameters by reference in many funcs and gcc cleaning @@ -226,9 +229,12 @@ public: VertexType *v0=pos.V(0); VertexType *v1=pos.V(1); - if(! (( (!v0->IsD()) && (!v1->IsD())) && - localMark>=v0->IMark() && - localMark>=v1->IMark())) + //if(! (( (!v0->IsD()) && (!v1->IsD())) && + // localMark>=v0->IMark() && + // localMark>=v1->IMark())) + if( v0->IsD() || v1->IsD() || + localMark < v0->IMark() || + localMark < v1->IMark() ) { ++FailStat::OutOfDate(); return false; diff --git a/vcg/complex/local_optimization/tri_edge_collapse_quadric.h b/vcg/complex/local_optimization/tri_edge_collapse_quadric.h index e1b442e3..b96df0fd 100644 --- a/vcg/complex/local_optimization/tri_edge_collapse_quadric.h +++ b/vcg/complex/local_optimization/tri_edge_collapse_quadric.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.5 2004/12/10 01:07:15 cignoni +Moved param classes inside; added support for optimal placement and symmetric; added update heap also here (not only in the base class) + Revision 1.4 2004/11/23 10:34:23 cignoni passed parameters by reference in many funcs and gcc cleaning @@ -209,45 +212,48 @@ public: InitQuadric(m); // Initialize the heap with all the possible collapses - if(IsSymmetric()) { // if the collapse is symmetric (e.g. u->v == v->u) - for(vi=m.vert.begin();vi!=m.vert.end();++vi) + if(IsSymmetric()) + { // if the collapse is symmetric (e.g. u->v == v->u) + for(vi=m.vert.begin();vi!=m.vert.end();++vi) if((*vi).IsRW()) { vcg::face::VFIterator<FaceType> x; for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x){ - x.F()->V1(x.I())->ClearV(); - x.F()->V2(x.I())->ClearV(); - } - for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++x ){ + x.V1()->ClearV(); + x.V2()->ClearV(); + } + for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++x ) + { assert(x.F()->V(x.I())==&(*vi)); - if((x.F()->V(x.I())<x.F()->V1(x.I())) && x.F()->V1(x.I())->IsRW() && !x.F()->V1(x.I())->IsV()){ - x.F()->V1(x.I())->SetV(); - - h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.F()->V(x.I()),x.F()->V1(x.I())),GlobalMark()))); + if((x.V0()<x.V1()) && x.V1()->IsRW() && !x.V1()->IsV()){ + x.V1()->SetV(); + h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.V0(),x.V1()),GlobalMark() ))); } - if((x.F()->V(x.I())<x.F()->V2(x.I())) && x.F()->V2(x.I())->IsRW()&& !x.F()->V2(x.I())->IsV()){ - x.F()->V2(x.I())->SetV(); - h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.F()->V(x.I()),x.F()->V2(x.I())),GlobalMark() ))); + if((x.V0()<x.V2()) && x.V2()->IsRW()&& !x.V2()->IsV()){ + x.V2()->SetV(); + h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.V0(),x.V2()),GlobalMark() ))); } } - } - } - else { // if the collapse is A-symmetric (e.g. u->v != v->u) + } + } + else + { // if the collapse is A-symmetric (e.g. u->v != v->u) for(vi=m.vert.begin();vi!=m.vert.end();++vi) - { - vcg::face::VFIterator<FaceType> x; - m.UnMarkAll(); - for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x){ - assert(x.F()->V(x.I())==&(*vi)); - if(x.F()->V(x.I())->IsRW() && x.F()->V1(x.I())->IsRW() && !m.IsMarked(x.F()->V1(x.I()))){ - h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.F()->V(x.I()),x.F()->V1(x.I())),GlobalMark()))); - } - if(x.F()->V(x.I())->IsRW() && x.F()->V2(x.I())->IsRW()&& !m.IsMarked(x.F()->V2(x.I()))){ - h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.F()->V(x.I()),x.F()->V2(x.I())),GlobalMark()))); - } - } - } - } + { + vcg::face::VFIterator<FaceType> x; + m.UnMarkAll(); + for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x) + { + assert(x.F()->V(x.I())==&(*vi)); + if(x.V()->IsRW() && x.V1()->IsRW() && !m.IsMarked(x.F()->V1(x.I()))){ + h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.V(),x.V1()),GlobalMark()))); + } + if(x.V()->IsRW() && x.V2()->IsRW() && !m.IsMarked(x.F()->V2(x.I()))){ + h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.V(),x.V2()),GlobalMark()))); + } + } + } + } make_heap(h_ret.begin(),h_ret.end()); } @@ -370,53 +376,59 @@ public: // inline void UpdateHeap(HeapType & h_ret) { - GlobalMark()++; int nn=0; + GlobalMark()++; VertexType *v[2]; v[0]= pos.V(0);v[1]=pos.V(1); v[1]->IMark() = GlobalMark(); // First loop around the remaining vertex to unmark visited flags - vcg::face::VFIterator<FaceType> vfi(v[1]->VFp(),v[1]->VFi()); + vcg::face::VFIterator<FaceType> vfi(v[1]); while (!vfi.End()){ - vfi.F()->V1(vfi.I())->ClearV(); - vfi.F()->V2(vfi.I())->ClearV(); + vfi.V1()->ClearV(); + vfi.V2()->ClearV(); ++vfi; } // Second Loop - vfi.F() = v[1]->VFp(); - vfi.I() = v[1]->VFi(); - while (!vfi.End()) + vfi = face::VFIterator<FaceType>(v[1]); + while (!vfi.End()) { assert(!vfi.F()->IsD()); for (int j=0;j<3;j++) { - if( !(vfi.F()->V1(vfi.I())->IsV()) && (vfi.F()->V1(vfi.I())->IsRW())) + if( !(vfi.V1()->IsV()) && vfi.V1()->IsRW()) { - vfi.F()->V1(vfi.I())->SetV(); - h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V(vfi.I()),vfi.F()->V1(vfi.I())),GlobalMark()))); - std::push_heap(h_ret.begin(),h_ret.end()); - if(!IsSymmetric()){ - h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V1(vfi.I()),vfi.F()->V(vfi.I())),GlobalMark()))); - std::push_heap(h_ret.begin(),h_ret.end()); - } - } - if( !(vfi.F()->V2(vfi.I())->IsV()) && (vfi.F()->V2(vfi.I())->IsRW())) + vfi.V1()->SetV(); + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V0(),vfi.V1()), GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + if(!IsSymmetric()){ + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V1(),vfi.V0()), GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + } + } + if( !(vfi.V2()->IsV()) && vfi.V2()->IsRW()) { - vfi.F()->V2(vfi.I())->SetV(); - h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V(vfi.I()),vfi.F()->V2(vfi.I())),GlobalMark()))); - std::push_heap(h_ret.begin(),h_ret.end()); - if(!IsSymmetric()){ - h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V2(vfi.I()),vfi.F()->V(vfi.I())),GlobalMark()))); - std::push_heap(h_ret.begin(),h_ret.end()); - } - } - - + vfi.V2()->SetV(); + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V0(),vfi.V2()),GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + if(!IsSymmetric()){ + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V2(),vfi.V0()), GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + } + } + if(Params().SafeHeapUpdate && vfi.V1()->IsRW() && vfi.V2()->IsRW() ) + { + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V1(),vfi.V2()),GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + if(!IsSymmetric()){ + h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V2(),vfi.V1()), GlobalMark()))); + std::push_heap(h_ret.begin(),h_ret.end()); + } + } } - ++vfi;nn++; + ++vfi; } -// printf("ADDED %d\n",nn); + } static void InitQuadric(TriMeshType &m)