Better management of symmetric/asymmetric edge collapses

This commit is contained in:
Paolo Cignoni 2005-01-19 10:35:28 +00:00
parent 4224284dc4
commit 1509a9b434
2 changed files with 80 additions and 62 deletions

View File

@ -22,6 +22,9 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
$Log: not supported by cvs2svn $ $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 Revision 1.14 2004/11/23 10:34:23 cignoni
passed parameters by reference in many funcs and gcc cleaning passed parameters by reference in many funcs and gcc cleaning
@ -226,9 +229,12 @@ public:
VertexType *v0=pos.V(0); VertexType *v0=pos.V(0);
VertexType *v1=pos.V(1); VertexType *v1=pos.V(1);
if(! (( (!v0->IsD()) && (!v1->IsD())) && //if(! (( (!v0->IsD()) && (!v1->IsD())) &&
localMark>=v0->IMark() && // localMark>=v0->IMark() &&
localMark>=v1->IMark())) // localMark>=v1->IMark()))
if( v0->IsD() || v1->IsD() ||
localMark < v0->IMark() ||
localMark < v1->IMark() )
{ {
++FailStat::OutOfDate(); ++FailStat::OutOfDate();
return false; return false;

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $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 Revision 1.4 2004/11/23 10:34:23 cignoni
passed parameters by reference in many funcs and gcc cleaning passed parameters by reference in many funcs and gcc cleaning
@ -209,41 +212,44 @@ public:
InitQuadric(m); InitQuadric(m);
// Initialize the heap with all the possible collapses // Initialize the heap with all the possible collapses
if(IsSymmetric()) { // if the collapse is symmetric (e.g. u->v == v->u) if(IsSymmetric())
{ // if the collapse is symmetric (e.g. u->v == v->u)
for(vi=m.vert.begin();vi!=m.vert.end();++vi) for(vi=m.vert.begin();vi!=m.vert.end();++vi)
if((*vi).IsRW()) if((*vi).IsRW())
{ {
vcg::face::VFIterator<FaceType> x; vcg::face::VFIterator<FaceType> x;
for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x){ for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x){
x.F()->V1(x.I())->ClearV(); x.V1()->ClearV();
x.F()->V2(x.I())->ClearV(); x.V2()->ClearV();
} }
for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++x ){ for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++x )
{
assert(x.F()->V(x.I())==&(*vi)); 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()){ if((x.V0()<x.V1()) && x.V1()->IsRW() && !x.V1()->IsV()){
x.F()->V1(x.I())->SetV(); x.V1()->SetV();
h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.V0(),x.V1()),GlobalMark() )));
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())<x.F()->V2(x.I())) && x.F()->V2(x.I())->IsRW()&& !x.F()->V2(x.I())->IsV()){ if((x.V0()<x.V2()) && x.V2()->IsRW()&& !x.V2()->IsV()){
x.F()->V2(x.I())->SetV(); x.V2()->SetV();
h_ret.push_back(HeapElem(new MYTYPE(EdgeType(x.F()->V(x.I()),x.F()->V2(x.I())),GlobalMark() ))); 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) for(vi=m.vert.begin();vi!=m.vert.end();++vi)
{ {
vcg::face::VFIterator<FaceType> x; vcg::face::VFIterator<FaceType> x;
m.UnMarkAll(); m.UnMarkAll();
for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x){ for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x)
{
assert(x.F()->V(x.I())==&(*vi)); 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()))){ if(x.V()->IsRW() && x.V1()->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()))); h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.V(),x.V1()),GlobalMark())));
} }
if(x.F()->V(x.I())->IsRW() && x.F()->V2(x.I())->IsRW()&& !m.IsMarked(x.F()->V2(x.I()))){ if(x.V()->IsRW() && x.V2()->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()))); h_ret.push_back( HeapElem( new MYTYPE( EdgeType (x.V(),x.V2()),GlobalMark())));
} }
} }
} }
@ -370,53 +376,59 @@ public:
// //
inline void UpdateHeap(HeapType & h_ret) inline void UpdateHeap(HeapType & h_ret)
{ {
GlobalMark()++; int nn=0; GlobalMark()++;
VertexType *v[2]; VertexType *v[2];
v[0]= pos.V(0);v[1]=pos.V(1); v[0]= pos.V(0);v[1]=pos.V(1);
v[1]->IMark() = GlobalMark(); v[1]->IMark() = GlobalMark();
// First loop around the remaining vertex to unmark visited flags // 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()){ while (!vfi.End()){
vfi.F()->V1(vfi.I())->ClearV(); vfi.V1()->ClearV();
vfi.F()->V2(vfi.I())->ClearV(); vfi.V2()->ClearV();
++vfi; ++vfi;
} }
// Second Loop // Second Loop
vfi.F() = v[1]->VFp(); vfi = face::VFIterator<FaceType>(v[1]);
vfi.I() = v[1]->VFi();
while (!vfi.End()) while (!vfi.End())
{ {
assert(!vfi.F()->IsD()); assert(!vfi.F()->IsD());
for (int j=0;j<3;j++) 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(); vfi.V1()->SetV();
h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V(vfi.I()),vfi.F()->V1(vfi.I())),GlobalMark()))); h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V0(),vfi.V1()), GlobalMark())));
std::push_heap(h_ret.begin(),h_ret.end()); std::push_heap(h_ret.begin(),h_ret.end());
if(!IsSymmetric()){ if(!IsSymmetric()){
h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V1(vfi.I()),vfi.F()->V(vfi.I())),GlobalMark()))); h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V1(),vfi.V0()), GlobalMark())));
std::push_heap(h_ret.begin(),h_ret.end()); std::push_heap(h_ret.begin(),h_ret.end());
} }
} }
if( !(vfi.F()->V2(vfi.I())->IsV()) && (vfi.F()->V2(vfi.I())->IsRW())) if( !(vfi.V2()->IsV()) && vfi.V2()->IsRW())
{ {
vfi.F()->V2(vfi.I())->SetV(); vfi.V2()->SetV();
h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V(vfi.I()),vfi.F()->V2(vfi.I())),GlobalMark()))); h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V0(),vfi.V2()),GlobalMark())));
std::push_heap(h_ret.begin(),h_ret.end()); std::push_heap(h_ret.begin(),h_ret.end());
if(!IsSymmetric()){ if(!IsSymmetric()){
h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.F()->V2(vfi.I()),vfi.F()->V(vfi.I())),GlobalMark()))); h_ret.push_back(HeapElem(new MYTYPE(EdgeType (vfi.V2(),vfi.V0()), GlobalMark())));
std::push_heap(h_ret.begin(),h_ret.end()); 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++;
} }
// printf("ADDED %d\n",nn); }
++vfi;
}
} }
static void InitQuadric(TriMeshType &m) static void InitQuadric(TriMeshType &m)