diff --git a/vcg/complex/trimesh/update/quality.h b/vcg/complex/trimesh/update/quality.h new file mode 100644 index 00000000..a9043521 --- /dev/null +++ b/vcg/complex/trimesh/update/quality.h @@ -0,0 +1,155 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.2 2004/03/29 14:26:57 cignoni +First working version! + +****************************************************************************/ + +#ifndef __VCG_TRI_UPDATE_QUALITY +#define __VCG_TRI_UPDATE_QUALITY + + +namespace vcg { +namespace tri { +/** \addtogroup trimesh */ +/*@{*/ +/// Generation of per-vertex and per-face Qualities according to various strategy. +/// This class is used to compute per face or per vertex color with respect to for example Border (UpdateColor::VertexBorderFlag), Selection (UpdateColor::FaceSelected), Quality . + +template +class UpdateQuality +{ +public: + typedef UpdateMeshType MeshType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::VertexPointer VertexPointer; + typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::FacePointer FacePointer; + typedef typename MeshType::FaceIterator FaceIterator; + +class VQualityHeap +{ +public: + float q; + VertexPointer p; + inline VQualityHeap( VertexPointer np ) + { + q = np->Q(); + p = np; + } + // Attenzione il minore e' maggiore + inline bool operator < ( const VQualityHeap & vq ) const { return q > vq.q; } + inline bool operator == ( const VQualityHeap & vq ) const { return q == vq.q; } + inline bool operator > ( const VQualityHeap & vq ) const { return q < vq.q; } + inline bool operator != ( const VQualityHeap & vq ) const { return q != vq.q; } + inline bool operator <= ( const VQualityHeap & vq ) const { return q >= vq.q; } + inline bool operator >= ( const VQualityHeap & vq ) const { return q <= vq.q; } + inline bool is_valid() const { return q==p->Q(); } +}; + + + +// REQUIREMENT VF topology and Border FLags +// Calcola la qualita' come distanza geodesica dal bordo della mesh. +// Robusta funziona anche per mesh non manifold. +// La qualita' memorizzata indica la distanza assoluta dal bordo della mesh. +// Nota prima del 13/11/03 in alcuni casi rari SPT andava in loop perche' poteva capitare +// che per approx numeriche ben strane pw->Q() > pv->Q()+d ma durante la memorizzazione +// della nuova distanza essa rimanesse uguale a prima. Patchato rimettendo i vertici nello +// heap solo se migliorano la distanza di un epsilon == 1/100000 della mesh diag. + +static void VertexGeodesicFromBorder(MeshType &m) // R1 +{ + //Requirements + assert(m.HasVFTopology()); + assert(m.HasPerVertexQuality()); + + vector heap; + VertexIterator v; + FaceIterator f; + int j; + + for(v=m.vert.begin();v!=m.vert.end();++v) + (*v).Q() = -1; + for(f=m.face.begin();f!=m.face.end();++f) // Inserisco nell'heap i v di bordo + if(!(*f).IsD()) + for(j=0;j<3;++j) + if( (*f).IsB(j) ) + { + for(int k=0;k<2;++k) + { + VertexPointer pv = (*f).V((j+k)%3); + if( pv->Q()==-1 ) + { + pv->Q() = 0; + heap.push_back(VQualityHeap(pv)); + } + } + } + + const MeshType::ScalarType loc_eps=m.bbox.Diag()/MeshType::ScalarType(100000); + while( heap.size()!=0 ) // Shortest path tree + { + VertexPointer pv; + pop_heap(heap.begin(),heap.end()); + if( ! heap.back().is_valid() ) + { + heap.pop_back(); + continue; + } + pv = heap.back().p; + heap.pop_back(); + MeshType::vedgepos_type x; + for( x.f = pv->Fp(), x.z = pv->Zp(); x.f!=0; x.NextF() ) + { + for(int k=0;k<2;++k) + { + VertexPointer pw; + float d; + if(k==0) pw = x.f->V1(x.z); + else pw = x.f->V2(x.z); + d = Distance(pv->P(),pw->P()); + if( pw->Q()==-1 || pw->Q() > pv->Q()+d + loc_eps) + { + pw->Q() = pv->Q()+d; + heap.push_back(VQualityHeap(pw)); + push_heap(heap.begin(),heap.end()); + } + } + } + } + + for(v=m.vert.begin();v!=m.vert.end();++v) + if(v->Q()==-1) + v->Q() = 0; +} + +}; //end class +} // end namespace +} // end namespace +#endif \ No newline at end of file