From cd8bf134e7ef4fd5c753b9063cf6b16e16aac2e4 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Sun, 5 Jun 2011 23:52:23 +0000 Subject: [PATCH] Moved (and removed qt dependencies and CMeshO stuff) everyithing from here to the vcg library --- .../filter_meshing/quadric_tex_simp.cpp | 10 +- .../filter_meshing/quadric_tex_simp.h | 756 +----------------- 2 files changed, 12 insertions(+), 754 deletions(-) diff --git a/src/meshlabplugins/filter_meshing/quadric_tex_simp.cpp b/src/meshlabplugins/filter_meshing/quadric_tex_simp.cpp index 7ef76bb9b..669eba2e1 100644 --- a/src/meshlabplugins/filter_meshing/quadric_tex_simp.cpp +++ b/src/meshlabplugins/filter_meshing/quadric_tex_simp.cpp @@ -32,13 +32,13 @@ void QuadricTexSimplification(CMeshO &m,int TargetFaceNum, bool Selected, tri:: { math::Quadric QZero; QZero.SetZero(); - QuadricTemp TD3(m.vert,QZero); - QuadricTexHelper::TDp3()=&TD3; + QuadricTexHelper::QuadricTemp TD3(m.vert,QZero); + QuadricTexHelper::TDp3()=&TD3; - QVector ,Quadric5 > > qv; + std::vector,Quadric5 > > qv; - Quadric5Temp TD(m.vert,qv); - QuadricTexHelper::TDp()=&TD; + QuadricTexHelper::Quadric5Temp TD(m.vert,qv); + QuadricTexHelper::TDp()=&TD; if(Selected) // simplify only inside selected faces { diff --git a/src/meshlabplugins/filter_meshing/quadric_tex_simp.h b/src/meshlabplugins/filter_meshing/quadric_tex_simp.h index 53473ccd4..42259ad58 100644 --- a/src/meshlabplugins/filter_meshing/quadric_tex_simp.h +++ b/src/meshlabplugins/filter_meshing/quadric_tex_simp.h @@ -23,761 +23,19 @@ #ifndef __QUADRICTEXSIMP_H #define __QUADRICTEXSIMP_H -#include -#include -#include -#include -namespace vcg +#include + +namespace vcg { namespace tri { +typedef BasicVertexPair VertexPair; -class TriEdgeCollapseQuadricTexParameter : public BaseParameterClass -{ -public: - double QualityThr; // all - double BoundaryWeight; - double NormalThr; - double CosineThr; - double QuadricEpsilon; - double ScaleFactor; - float ExtraTCoordWeight; - bool UseArea; - bool UseVertexWeight; - bool NormalCheck; - bool QualityCheck; - bool QualityQuadric; - bool OptimalPlacement; - bool MemoryLess; - bool ComplexCheck; - bool ScaleIndependent; -//*********************** - bool PreserveTopology; - bool PreserveBoundary; - bool MarkComplex; - bool SafeHeapUpdate; - - TriEdgeCollapseQuadricTexParameter() - { - SetDefaultParams(); - } - - void SetDefaultParams() - { - UseArea=true; - UseVertexWeight=false; - NormalCheck=false; - NormalThr=M_PI/2; - QualityCheck=true; - QualityThr=.1; - BoundaryWeight=.5; - OptimalPlacement=true; - ScaleIndependent=true; - ComplexCheck=false; - QuadricEpsilon =1e-15; - ScaleFactor=1.0; - ExtraTCoordWeight=0.0; - QualityQuadric = false; - PreserveTopology = false; - } -}; - - -typedef SimpleTempData > > > Quadric5Temp; -typedef SimpleTempData > QuadricTemp; - - -// This is a static class that contains the references for the simple temporary data for the current mesh. -// for each vertex we keep a classic Quadric3D and a vector of pairs texcoord+Quadric5D - -class QuadricTexHelper - { - public: - - QuadricTexHelper(){}; - - - static void Init(){}; - - // it allocs the QPair for the vertex relativly to the texture coord parameter - static void Alloc(CVertexO *v,vcg::TexCoord2f &coord) - { - QVector > > &qv = Vd(v); - Quadric5 newq5; - newq5.Zero(); - vcg::TexCoord2f newcoord; - newcoord.u() = coord.u(); - newcoord.v() = coord.v(); - - newq5.Sum3(Qd3(v),coord.u(),coord.v()); - - qv.push_back(QPair >(newcoord,newq5)); - } - - static void SumAll(CVertexO *v,vcg::TexCoord2f &coord, Quadric5& q) - { - QVector > > &qv = Vd(v); - - for(int i = 0; i < qv.size(); i++) - { - vcg::TexCoord2f &f = qv[i].first; - if((f.u() == coord.u()) && (f.v() == coord.v())) - qv[i].second += q; - else - qv[i].second.Sum3(Qd3(v),f.u(),f.v()); - } - } - - static bool Contains(CVertexO *v,vcg::TexCoord2f &coord) - { - QVector > > &qv = Vd(v); - - for(int i = 0; i < qv.size(); i++) - { - vcg::TexCoord2f &f = qv[i].first; - if((f.u() == coord.u()) && (f.v() == coord.v())) - return true; - } - - return false; - } - - static Quadric5 &Qd(CVertexO *v,vcg::TexCoord2f &coord) - { - QVector > > &qv = Vd(v); - - for(int i = 0; i < qv.size(); i++) - { - vcg::TexCoord2f &f = qv[i].first; - if((f.u() == coord.u()) && (f.v() == coord.v())) - return qv[i].second; - } - - assert(0); - } - static math::Quadric &Qd3(CVertexO *v) {return TD3()[*v];} - static math::Quadric &Qd3(CVertexO &v) {return TD3()[v];} - - static QVector > > &Vd(CVertexO *v){return (TD()[*v]);} - static CVertexO::ScalarType W(CVertexO * /*v*/) {return 1.0;}; - static CVertexO::ScalarType W(CVertexO & /*v*/) {return 1.0;}; - static void Merge(CVertexO & /*v_dest*/, CVertexO const & /*v_del*/){}; - static Quadric5Temp* &TDp() {static Quadric5Temp *td; return td;} - static Quadric5Temp &TD() {return *TDp();} - static QuadricTemp* &TDp3() {static QuadricTemp *td3; return td3;} - static QuadricTemp &TD3() {return *TDp3();} - }; - - - -template > -class TriEdgeCollapseQuadricTex: public vcg::tri::TriEdgeCollapse< TriMeshType, VertexPair, MYTYPE> -{ - typedef HelperType QH; - typedef typename tri::TriEdgeCollapse::HeapType HeapType; - typedef typename tri::TriEdgeCollapse::HeapElem HeapElem; - typedef typename TriMeshType::FaceType FaceType; - typedef typename TriMeshType::VertexType VertexType; - typedef typename TriMeshType::CoordType CoordType; - typedef typename TriMeshType::CoordType::ScalarType ScalarType; - typedef typename TriMeshType::VertexPointer VertexPointer; - - - public: - - inline TriEdgeCollapseQuadricTex(const VertexPair &p, int mark, BaseParameterClass *_pp) - { - TriEdgeCollapseQuadricTexParameter *pp = (TriEdgeCollapseQuadricTexParameter *)_pp; - this->localMark = mark; - this->pos=p; - this->_priority = ComputePriority(pp); - } - -// puntatori ai vertici che sono stati messi non-w per preservare il boundary - static std::vector & WV(){ - static std::vector _WV; return _WV; - }; - - - - static TriEdgeCollapseQuadricTexParameter & Params(){static TriEdgeCollapseQuadricTexParameter p; return p;} - - // Final Clean up after the end of the simplification process - static void Finalize(TriMeshType &m,HeapType & /*h_ret*/, BaseParameterClass *_pp) - { - TriEdgeCollapseQuadricTexParameter *pp = (TriEdgeCollapseQuadricTexParameter *)_pp; - vcg::tri::UpdateFlags::FaceBorderFromVF(m); - - // If we had the boundary preservation we should clean up the writable flags - if(pp->PreserveBoundary) - { - typename std::vector::iterator wvi; - for(wvi=WV().begin();wvi!=WV().end();++wvi) - if(!(*wvi)->IsD()) (*wvi)->SetW(); - } - } - - - - - inline static int matchVertexID(FaceType *f,VertexType *v) - { - if(f->V(0)==v) return 0; - if(f->V(1)==v) return 1; - if(f->V(2)==v) return 2; - - assert(0); return -1; - } - - inline int GetTexCoords(vcg::TexCoord2f &tcoord0_1,vcg::TexCoord2f &tcoord1_1,vcg::TexCoord2f &tcoord0_2,vcg::TexCoord2f &tcoord1_2) - { - int ncoords = 0; - - vcg::face::VFIterator vfi(this->pos.V(0)); - - for(vfi.F() = this->pos.V(0)->VFp(), vfi.I() = this->pos.V(0)->VFi(); vfi.F()!=0; ++vfi ) // for all faces in v0 - if(vfi.F()->V(0)==this->pos.V(1) || vfi.F()->V(1)==this->pos.V(1) || vfi.F()->V(2)==this->pos.V(1) ) // and v1 - { - if(ncoords == 0) - { - tcoord0_1 = vfi.F()->WT(matchVertexID(vfi.F(),this->pos.V(0))); - tcoord1_1 = vfi.F()->WT(matchVertexID(vfi.F(),this->pos.V(1))); - } - else - { - tcoord0_2 = vfi.F()->WT(matchVertexID(vfi.F(),this->pos.V(0))); - tcoord1_2 = vfi.F()->WT(matchVertexID(vfi.F(),this->pos.V(1))); - - if( - (tcoord0_1.u() == tcoord0_2.u()) && - (tcoord0_1.v() == tcoord0_2.v()) && - (tcoord1_1.u() == tcoord1_2.u()) && - (tcoord1_1.v() == tcoord1_2.v()) - ) - return 1; - else - return 2; - } - - ncoords++; - } - - return ncoords; - } - - - ScalarType ComputePriority(BaseParameterClass *_pp) - { - TriEdgeCollapseQuadricTexParameter *pp = (TriEdgeCollapseQuadricTexParameter *)_pp; - Quadric5 qsum1; - Quadric5 qsum2; - double min1[5]; - double min2[5]; - vcg::TexCoord2f tcoord0_1; - vcg::TexCoord2f tcoord1_1; - vcg::TexCoord2f tcoord0_2; - vcg::TexCoord2f tcoord1_2; - int ncoords; - - ncoords = GetTexCoords(tcoord0_1,tcoord1_1,tcoord0_2,tcoord1_2); - - return (ScalarType)ComputeMinimalsAndPriority(min1,min2,qsum1,qsum2,tcoord0_1,tcoord1_1,tcoord0_2,tcoord1_2,ncoords,pp); - } - - - /* - * the very important function that says how good is a collapse. - Originally is should be just the quadric error (e.g. you should choose the collapse that make the minimal quadric error) - but important correcting factors has to be applyed - - quality of the involved triangles - - normal checking - */ - ScalarType ComputeTexPriority(double vv[5],Quadric5 &qsum, BaseParameterClass *_pp) - { - TriEdgeCollapseQuadricTexParameter *pp = (TriEdgeCollapseQuadricTexParameter *)_pp; - VertexType * v[2]; - v[0] = this->pos.V(0); - v[1] = this->pos.V(1); - - //// Move the two vertexe into new position (storing the old ones) - CoordType OldPos0=v[0]->P(); - CoordType OldPos1=v[1]->P(); - - v[0]->P() = CoordType(vv[0],vv[1],vv[2]); - //v[0]->P() = (v[0]->P()+v[1]->P())/2.0; - v[1]->P()=v[0]->P(); - - double QuadErr = qsum.Apply(vv); - - //// Rescan faces and compute quality and difference between normals - int i; - - double qt, MinQual = 1e100; - vcg::face::VFIterator x(this->pos.V(0)); - - double ndiff,MinCos = 1e100; // minimo coseno di variazione di una normale della faccia - // (e.g. max angle) Mincos varia da 1 (normali coincidenti) a - // -1 (normali opposte); - - for(x.F() = v[0]->VFp(), x.I() = v[0]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v0 - if(x.F()->V(0)!=v[1] && x.F()->V(1)!=v[1] && x.F()->V(2)!=v[1] ) // skip faces with v1 - { - qt= QualityFace(*x.F()); - if(qtNormalCheck){ - Point3f nn=NormalizedNormal(*x.F()); - ndiff=nn.dot(x.F()->N()) / x.F()->N().Norm(); - if(ndiffVFp(), x.I() = v[1]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v1 - if(x.F()->V(0)!=v[0] && x.F()->V(1)!=v[0] && x.F()->V(2)!=v[0] ) // skip faces with v0 - { - qt= QualityFace(*x.F()); - if(qtNormalCheck){ - Point3f nn=NormalizedNormal(*x.F()); - ndiff=nn.dot(x.F()->N() / x.F()->N().Norm()); - if(ndiff have no penalty; - if(MinQual>pp->QualityThr) MinQual=pp->QualityThr; - if(QuadErr<1e-15) QuadErr=1e-15; // Do not use zero quality penalties - - this->_priority = (ScalarType)(QuadErr / MinQual); // the priority of collapses that create low quality triangles has a penalty (it is increased) - - - if(pp->NormalCheck){ - if(MinCosCosineThr) this->_priority *=1000; // gross penalty to collapses that move too much the original normals. - } - - - - //Restore old position of v0 and v1 - v[0]->P()=OldPos0; - v[1]->P()=OldPos1; - return this->_priority; - } - - inline ScalarType ComputeMinimalsAndPriority(double dest_1[5], - double dest_2[5], - Quadric5 &qsum_1, - Quadric5 &qsum_2, - vcg::TexCoord2f &tcoord0_1, - vcg::TexCoord2f &tcoord1_1, - vcg::TexCoord2f &tcoord0_2, - vcg::TexCoord2f &tcoord1_2, - int ncoords, - BaseParameterClass *_pp) - { - TriEdgeCollapseQuadricTexParameter *pp = (TriEdgeCollapseQuadricTexParameter *)_pp; - double tmp1[5]; - double tmp2[5]; - ScalarType priority1; - ScalarType priority2; - - tmp1[0] = this->pos.V(0)->P().X(); - tmp1[1] = this->pos.V(0)->P().Y(); - tmp1[2] = this->pos.V(0)->P().Z(); - tmp1[3] = tcoord0_1.u(); - tmp1[4] = tcoord0_1.v(); - - tmp2[0] = this->pos.V(1)->P().X(); - tmp2[1] = this->pos.V(1)->P().Y(); - tmp2[2] = this->pos.V(1)->P().Z(); - tmp2[3] = tcoord1_1.u(); - tmp2[4] = tcoord1_1.v(); - - - assert(QH::Qd(this->pos.V(0),tcoord0_1).IsValid()); - assert(QH::Qd(this->pos.V(1),tcoord1_1).IsValid()); - - qsum_1 = QH::Qd(this->pos.V(0),tcoord0_1); - qsum_1 += QH::Qd(this->pos.V(1),tcoord1_1); - - ComputeMinimal(dest_1,tmp1,tmp2,qsum_1,pp); - priority1 = ComputeTexPriority(dest_1,qsum_1,pp); - - if(ncoords < 2) - return priority1*(1 + (pp->ExtraTCoordWeight)*(QH::Vd(this->pos.V(0)).size()+ QH::Vd(this->pos.V(1)).size() - 2)); - - - tmp1[3] = tcoord0_2.u(); - tmp1[4] = tcoord0_2.v(); - - tmp2[3] = tcoord1_2.u(); - tmp2[4] = tcoord1_2.v(); - - assert(QH::Qd(this->pos.V(0),tcoord0_2).IsValid()); - assert(QH::Qd(this->pos.V(1),tcoord1_2).IsValid()); - - qsum_2 = QH::Qd(this->pos.V(0),tcoord0_2); - qsum_2 += QH::Qd(this->pos.V(1),tcoord1_2); - - ComputeMinimal(dest_2,tmp1,tmp2,qsum_2,pp); - priority2 = ComputeTexPriority(dest_2,qsum_2,pp); - - if(priority1 > priority2) - { - ComputeMinimalWithGeoContraints(dest_2,tmp1,tmp2,qsum_2,dest_1,pp); - priority2 = ComputeTexPriority(dest_2,qsum_2,pp); - } - else - { - ComputeMinimalWithGeoContraints(dest_1,tmp1,tmp2,qsum_1,dest_2,pp); - priority1 = ComputeTexPriority(dest_1,qsum_1,pp); - } - - - this->_priority = max(priority1, priority2)*(1 + (pp->ExtraTCoordWeight)*(QH::Vd(this->pos.V(0)).size()+QH::Vd(this->pos.V(1)).size() - 2)); - - return this->_priority; - } - - inline void ComputeMinimal(double vv[5],double v0[5],double v1[5], Quadric5 qsum,BaseParameterClass *_pp) - { - tri::TriEdgeCollapseQuadricParameter *pp =(tri::TriEdgeCollapseQuadricParameter *)_pp; - bool rt=qsum.Minimum(vv); - // if the computation of the minimum fails we choose between the two edge points and the middle one. - // Switch to this branch also in the case of not using the optimal placement. - if(!rt || !pp->OptimalPlacement ) { - - vv[0] = (v0[0] + v1[0])/2; - vv[1] = (v0[1] + v1[1])/2; - vv[2] = (v0[2] + v1[2])/2; - vv[3] = (v0[3] + v1[3])/2; - vv[4] = (v0[4] + v1[4])/2; - - // In the case of not using the optimal placement we have to be sure that the middle value is discarded. - double qvx= std::numeric_limits::max(); - if(pp->OptimalPlacement) - qvx = qsum.Apply(vv); - - - double qv0=qsum.Apply(v0); - double qv1=qsum.Apply(v1); - - - if(qv0 qsum, double geo[5],BaseParameterClass *_pp) - { - tri::TriEdgeCollapseQuadricParameter *pp =(tri::TriEdgeCollapseQuadricParameter *)_pp; - bool rt=qsum.MinimumWithGeoContraints(vv,geo); - // if the computation of the minimum fails we choose between the two edge points and the middle one. - // Switch to this branch also in the case of not using the optimal placement. - if(!rt || !pp->OptimalPlacement) { - double qvx = std::numeric_limits::max(); - vv[0] = geo[0]; - vv[1] = geo[1]; - vv[2] = geo[2]; - if(pp->OptimalPlacement) - { - vv[3] = (v0[3] + v1[3])/2; - vv[4] = (v0[4] + v1[4])/2; - qvx=qsum.Apply(vv); - } - vv[3] = v0[3]; - vv[4] = v0[4]; - - double qv0=qsum.Apply(vv); - - vv[3] = v1[3]; - vv[4] = v1[4]; - - double qv1=qsum.Apply(v1); - - vv[3] = (v0[3] + v1[3])/2; - vv[4] = (v0[4] + v1[4])/2; - - if(qv0IsR() &&(*pf).V(1)->IsR() &&(*pf).V(2)->IsR()) - { - Quadric5 q; - q.byFace(*pf, QH::Qd3((*pf).V(0)), QH::Qd3((*pf).V(1)), QH::Qd3((*pf).V(2)),pp->QualityQuadric); - - for(int j=0;j<3;++j) - if( (*pf).V(j)->IsW()) - { - if(!HelperType::Contains((*pf).V(j),(*pf).WT(j))) - { - HelperType::Alloc((*pf).V(j),(*pf).WT(j)); - } - - HelperType::SumAll((*pf).V(j),(*pf).WT(j),q); - } - - } - - } - - static void Init(TriMeshType &m,HeapType&h_ret,BaseParameterClass *_pp) - { - tri::TriEdgeCollapseQuadricParameter *pp =(tri::TriEdgeCollapseQuadricParameter *)_pp; - typename TriMeshType::VertexIterator vi; - typename TriMeshType::FaceIterator pf; - - vcg::tri::UpdateTopology::VertexFace(m); - vcg::tri::UpdateFlags::FaceBorderFromVF(m); - - if(pp->PreserveBoundary ) - { - WV().clear(); - for(pf=m.face.begin();pf!=m.face.end();++pf) - if( !(*pf).IsD() && (*pf).IsW() ) - for(int j=0;j<3;++j) - if((*pf).IsB(j)) - { - if((*pf).V(j)->IsW()) {(*pf).V(j)->ClearW(); WV().push_back((*pf).V(j));} - if((*pf).V1(j)->IsW()) {(*pf).V1(j)->ClearW();WV().push_back((*pf).V1(j));} - } - } - - InitQuadric(m,pp); - - // Initialize the heap with all the possible collapses - for(vi=m.vert.begin();vi!=m.vert.end();++vi) - if((*vi).IsRW()) - { - vcg::face::VFIterator x; - 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.V0()IsRW() && !x.V1()->IsV()){ - x.V1()->SetV(); - h_ret.push_back(HeapElem(new MYTYPE(VertexPair(x.V0(),x.V1()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),pp ))); - } - if((x.V0()IsRW()&& !x.V2()->IsV()){ - x.V2()->SetV(); - h_ret.push_back(HeapElem(new MYTYPE(VertexPair(x.V0(),x.V2()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),pp ))); - } - } - } - make_heap(h_ret.begin(),h_ret.end()); - } - - inline void UpdateHeap(HeapType & h_ret,BaseParameterClass *_pp) - { - tri::TriEdgeCollapseQuadricParameter *pp =(tri::TriEdgeCollapseQuadricParameter *)_pp; - this->GlobalMark()++; - VertexType *v[2]; - v[0]= this->pos.V(0); - v[1]= this->pos.V(1); - v[1]->IMark() = this->GlobalMark(); - - // First loop around the remaining vertex to unmark visited flags - vcg::face::VFIterator vfi(v[1]); - - while (!vfi.End()){ - vfi.V1()->ClearV(); - vfi.V2()->ClearV(); - ++vfi; - } - - // Second Loop - vfi = face::VFIterator(v[1]); - while (!vfi.End()) - { - assert(!vfi.F()->IsD()); - for (int j=0;j<3;j++) - { - - if( !(vfi.V1()->IsV()) && vfi.V1()->IsRW()) - { - vfi.V1()->SetV(); - - h_ret.push_back(HeapElem(new MYTYPE(VertexPair(vfi.V0(),vfi.V1()), this->GlobalMark(),pp))); - std::push_heap(h_ret.begin(),h_ret.end()); - } - - if( !(vfi.V2()->IsV()) && vfi.V2()->IsRW()) - { - vfi.V2()->SetV(); - - h_ret.push_back(HeapElem(new MYTYPE(VertexPair(vfi.V0(),vfi.V2()),this->GlobalMark(),pp))); - std::push_heap(h_ret.begin(),h_ret.end()); - } - } - ++vfi; - } - } - - void Execute(TriMeshType &m, BaseParameterClass *_pp) - { - tri::TriEdgeCollapseQuadricParameter *pp =(tri::TriEdgeCollapseQuadricParameter *)_pp; - Quadric5 qsum1; - Quadric5 qsum2; - double min1[5]; - double min2[5]; - vcg::TexCoord2f tcoord0_1; - vcg::TexCoord2f tcoord1_1; - vcg::TexCoord2f tcoord0_2; - vcg::TexCoord2f tcoord1_2; - vcg::TexCoord2f newtcoord1; - vcg::TexCoord2f newtcoord2; - QVector > > qv; - int ncoords; - VertexType * v[2]; - v[0] = this->pos.V(0); - v[1] = this->pos.V(1); - - math::Quadric qsum3 = QH::Qd3(v[0]); - qsum3 += QH::Qd3(v[1]); - - ncoords = GetTexCoords(tcoord0_1,tcoord1_1,tcoord0_2,tcoord1_2); - - ComputeMinimalsAndPriority(min1,min2,qsum1,qsum2,tcoord0_1,tcoord1_1,tcoord0_2,tcoord1_2,ncoords,pp); - - CoordType newPos(min1[0],min1[1],min1[2]); /* it's the same as min2[0],min2[1],min2[2] since the geometrical - constraint has been imposed during the re-computation of the other minimal */ - - - EdgeCollapser::Do(m, this->pos, newPos); - //DoCollapse(m, this->pos, newPos ); // v0 is deleted and v1 take the new position - - vcg::TexCoord2f newtcoord; - Quadric5 newq; - - - - newtcoord.u() = (float)min1[3]; - newtcoord.v() = (float)min1[4]; - newtcoord1 = newtcoord; - newq = qsum1; - - qv.push_back(QPair >(newtcoord,newq)); - - if(ncoords > 1) - { - newtcoord.u() = min2[3]; - newtcoord.v() = min2[4]; - newtcoord2 = newtcoord; - newq = qsum2; - - qv.push_back(QPair >(newtcoord2,newq)); - } - - - vcg::face::VFIterator vfi(v[1]); - while (!vfi.End()) - { - vcg::TexCoord2f & tcoords = vfi.F()->WT(matchVertexID(vfi.F(),v[1])); - - if( - ((tcoords.u() == tcoord0_1.u()) && (tcoords.v() == tcoord0_1.v())) || - ((tcoords.u() == tcoord1_1.u()) && (tcoords.v() == tcoord1_1.v())) - ) - { - tcoords.u() = newtcoord1.u(); - tcoords.v() = newtcoord1.v(); - } - else if( - (ncoords > 1) && - ( - ((tcoords.u() == tcoord0_2.u()) && (tcoords.v() == tcoord0_2.v())) || - ((tcoords.u() == tcoord1_2.u()) && (tcoords.v() == tcoord1_2.v())) - ) - ) - { - tcoords.u()= newtcoord2.u(); - tcoords.v()= newtcoord2.v(); - } - else - { - newtcoord = tcoords; - - if(QH::Contains(v[0],tcoords)) - { - newq = QH::Qd(v[0],tcoords); - newq.Sum3(QH::Qd3(v[1]),tcoords.u(),tcoords.v()); - } - else if(QH::Contains(v[1],tcoords)) - { - newq = QH::Qd(v[1],tcoords); - newq.Sum3(QH::Qd3(v[0]),tcoords.u(),tcoords.v()); - } - else - assert(0); - - qv.push_back(QPair >(newtcoord,newq)); - } - - ++vfi; - } - QH::Qd3(v[1]) = qsum3; - QH::Vd(v[1]) = qv; - - } - -}; - - -class QTVertexPair { -public: - inline QTVertexPair() {}; - inline QTVertexPair( CVertexO * v0, CVertexO * v1){V(0) = v0; V(1) = v1; }; - void Sort() {if(V(0) { +class MyTriEdgeCollapseQTex: public TriEdgeCollapseQuadricTex< CMeshO, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > { public: - typedef TriEdgeCollapseQuadricTex< CMeshO, QTVertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper> TECQ; - inline MyTriEdgeCollapseQTex( const QTVertexPair &p, int i,BaseParameterClass *pp) :TECQ(p,i,pp){} + typedef TriEdgeCollapseQuadricTex< CMeshO, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > TECQ; + inline MyTriEdgeCollapseQTex( const VertexPair &p, int i,BaseParameterClass *pp) :TECQ(p,i,pp){} }; } // end namespace tri