From 6295f96fbd5a7c05fff5447e88d4dd98fdd88fa4 Mon Sep 17 00:00:00 2001 From: cignoni Date: Mon, 9 Oct 2006 20:12:55 +0000 Subject: [PATCH] Heavyly restructured for meshlab inclusion. Now the access to the quadric elements are mediated by a static helper class. --- .../tri_edge_collapse_quadric.h | 101 +++++++++++------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/vcg/complex/local_optimization/tri_edge_collapse_quadric.h b/vcg/complex/local_optimization/tri_edge_collapse_quadric.h index 73b6d295..3653108f 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.9 2006/10/07 17:20:25 cignoni +Updated to the new style face->Normal() becomes Normal(face) + Revision 1.8 2005/10/02 23:19:36 cignoni Changed the sign of the priority of a collapse. Now it is its the error as it should (and not -error) @@ -75,10 +78,15 @@ namespace tri{ Requirements: Vertex - must have incremental mark must have: - field QuadricType Q; - member + incremental mark + VF topology + + must have: + members + + QuadricType Qd(); + ScalarType W() const; A per-vertex Weight that can be used in simplification lower weight means that error is lowered, @@ -89,27 +97,26 @@ namespace tri{ (e.g. its weight with the one of the given vertex, the color ect). Standard: void function; - Faces devono avere Shared Adjacency - durante la init serve FF per le quadriche di bordo - durante la semplificazione si usa VF + OtherWise the class should be templated with a static helper class that helps to retrieve these functions. + If the vertex class exposes these functions a default static helper class is provided. */ + //**Helper CLASSES**// + template + class QInfoStandard + { + public: + QInfoStandard(){}; + static void Init(){}; + static math::Quadric &Qd(VERTEX_TYPE &v) {return v.Qd();} + static math::Quadric &Qd(VERTEX_TYPE *v) {return v->Qd();} + static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE *v) {return 1.0;}; + static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE &v) {return 1.0;}; + static void Merge(VERTEX_TYPE & v_dest, VERTEX_TYPE const & v_del){}; + }; -template -class TriEdgeCollapseQuadric: public TriEdgeCollapse< TriMeshType,MYTYPE> -{ -public: - typedef typename vcg::tri::TriEdgeCollapse< TriMeshType, MYTYPE > TEC; - typedef typename TEC::EdgeType EdgeType; - typedef typename TriEdgeCollapse::HeapType HeapType; - typedef typename TriEdgeCollapse::HeapElem HeapElem; - typedef typename TriMeshType::CoordType CoordType; - typedef typename TriMeshType::ScalarType ScalarType; - typedef math::Quadric< double > QuadricType; - typedef typename TriMeshType::FaceType FaceType; - typedef typename TriMeshType::VertexType VertexType; -class QParameter +class TriEdgeCollapseQuadricParameter { public: double QualityThr; // all @@ -135,6 +142,22 @@ public: }; +template > +class TriEdgeCollapseQuadric: public TriEdgeCollapse< TriMeshType, MYTYPE> +{ +public: + typedef typename vcg::tri::TriEdgeCollapse< TriMeshType, MYTYPE > TEC; + typedef typename TEC::EdgeType EdgeType; + typedef typename TriEdgeCollapse::HeapType HeapType; + typedef typename TriEdgeCollapse::HeapElem HeapElem; + typedef typename TriMeshType::CoordType CoordType; + typedef typename TriMeshType::ScalarType ScalarType; + typedef math::Quadric< double > QuadricType; + typedef typename TriMeshType::FaceType FaceType; + typedef typename TriMeshType::VertexType VertexType; + typedef TriEdgeCollapseQuadricParameter QParameter; + typedef HelperType QH; + static QParameter & Params(){static QParameter p; return p;} enum Hint { HNHasFFTopology = 0x0001, // La mesh arriva con la topologia ff gia'fatta @@ -170,7 +193,8 @@ public: { CoordType newPos; if(Params().OptimalPlacement) newPos= ComputeMinimal(); else newPos=this->pos.V(1)->P(); - this->pos.V(1)->q+=this->pos.V(0)->q; + //this->pos.V(1)->Qd()+=this->pos.V(0)->Qd(); + QH::Qd(this->pos.V(1))+=QH::Qd(this->pos.V(0)); int FaceDel=DoCollapse(this->pos, newPos); // v0 is deleted and v1 take the new position m.fn-=FaceDel; --m.vn; @@ -351,8 +375,8 @@ public: } } - QuadricType qq=v[0]->q; - qq+=v[1]->q; + QuadricType qq=QH::Qd(v[0]); + qq+=QH::Qd(v[1]); double QuadErr = Params().ScaleFactor*qq.Apply(v[1]->P()); // All collapses involving triangles with quality larger than has no penalty; @@ -367,7 +391,7 @@ public: if(QuadErrW()+v[0]->W())/2; + if( Params().UseVertexWeight ) QuadErr *= (QH::W(v[1])+QH::W(v[0]))/2; if(!Params().QualityCheck && !Params().NormalCheck) error = (ScalarType)(QuadErr); if( Params().QualityCheck && !Params().NormalCheck) error = (ScalarType)(QuadErr / MinQual); @@ -447,10 +471,11 @@ static void InitQuadric(TriMeshType &m) typename TriMeshType::FaceIterator pf; typename TriMeshType::VertexIterator pv; int j; + QH::Init(); // m.ClearFlags(); for(pv=m.vert.begin();pv!=m.vert.end();++pv) // Azzero le quadriche if( ! (*pv).IsD() && (*pv).IsW()) - (*pv).q.Zero(); + QH::Qd(*pv).Zero(); for(pf=m.face.begin();pf!=m.face.end();++pf) @@ -472,7 +497,7 @@ static void InitQuadric(TriMeshType &m) q.ByPlane(p); for(j=0;j<3;++j) - if( (*pf).V(j)->IsW() ) (*pf).V(j)->q += q; // Sommo la quadrica ai vertici + if( (*pf).V(j)->IsW() ) QH::Qd((*pf).V(j)) += q; // Sommo la quadrica ai vertici for(j=0;j<3;++j) if( (*pf).IsB(j)) // Bordo! @@ -484,12 +509,12 @@ static void InitQuadric(TriMeshType &m) // poiche' la pesatura in funzione dell'area e'gia fatta in p.Direction() // Senza la normalize il bordo e' pesato in funzione della grandezza della mesh (mesh grandi non decimano sul bordo) pb.SetDirection(p.Direction() ^ ( (*pf).V1(j)->cP() - (*pf).V(j)->cP() ).Normalize()); - pb.SetDirection(pb.Direction()* Params().BoundaryWeight); // amplify border planes + pb.SetDirection(pb.Direction()* (ScalarType)Params().BoundaryWeight); // amplify border planes pb.SetOffset(pb.Direction() * (*pf).V(j)->cP()); q.ByPlane(pb); - if( (*pf).V (j)->IsW() ) (*pf).V (j)->q += q; // Sommo le quadriche - if( (*pf).V1(j)->IsW() ) (*pf).V1(j)->q += q; + if( (*pf).V (j)->IsW() ) QH::Qd((*pf).V (j)) += q; // Sommo le quadriche + if( (*pf).V1(j)->IsW() ) QH::Qd((*pf).V1(j)) += q; } } @@ -542,21 +567,21 @@ static void InitQuadric(TriMeshType &m) typename TriMeshType::VertexType * v[2]; v[0] = this->pos.V(0); v[1] = this->pos.V(1); - QuadricType q=v[0]->q; - q+=v[1]->q; + QuadricType q=QH::Qd(v[0]); + q+=QH::Qd(v[1]); - CoordType x; - bool rt=q.Minimum(x); - if(!rt) { - x=(v[0]->P()+v[1]->P())/2; + Point3 x; + bool rt=q.Minimum(x); + if(!rt) { // if the computation of the minimum fails we choose between the two edge points and the middle one. + x.Import((v[0]->P()+v[1]->P())/2); double qvx=q.Apply(x); double qv0=q.Apply(v[0]->P()); double qv1=q.Apply(v[1]->P()); - if(qv0P(); - if(qv1P(); + if(qv0P()); + if(qv1P()); } - return x; + return CoordType::Construct(x); } // //