From b389e3a314bf524579fbefaa74e2536153d6e2e0 Mon Sep 17 00:00:00 2001 From: cignoni Date: Tue, 17 Jun 2014 13:42:10 +0000 Subject: [PATCH] removed a few point3f and changed into coordTypes --- vcg/complex/algorithms/refine_loop.h | 886 ++++++++++++++------------- 1 file changed, 444 insertions(+), 442 deletions(-) diff --git a/vcg/complex/algorithms/refine_loop.h b/vcg/complex/algorithms/refine_loop.h index 095fb892..d643b5d4 100644 --- a/vcg/complex/algorithms/refine_loop.h +++ b/vcg/complex/algorithms/refine_loop.h @@ -21,10 +21,10 @@ * * ****************************************************************************/ /*! \file refine_loop.h - * + * * \brief This file contain code for Loop's subdivision scheme for triangular * mesh and some similar method. - * + * */ #ifndef __VCGLIB_REFINE_LOOP @@ -46,15 +46,15 @@ namespace tri{ /* Metodo di Loop dalla documentazione "Siggraph 2000 course on subdivision" - d4------d3 d4------d3 - / \ / \ / \ / \ u - / \ / \ / e4--e3 \ / \ + d4------d3 d4------d3 + / \ / \ / \ / \ u + / \ / \ / e4--e3 \ / \ / \/ \ / / \/ \ \ / \ d5------d1------d2 -> d5--e5--d1--e2--d2 l--M--r \ /\ / \ \ /\ / / \ / - \ / \ / \ e6--e7 / \ / - \ / \ / \ / \ / d - d6------d7 d6------d7 + \ / \ / \ e6--e7 / \ / + \ / \ / \ / \ / d + d6------d7 d6------d7 ******************************************************* @@ -62,141 +62,141 @@ d5------d1------d2 -> d5--e5--d1--e2--d2 l--M--r /*! * \brief Weight class for classical Loop's scheme. - * + * * See Zorin, D. & Schröeder, P.: Subdivision for modeling and animation. Proc. ACM SIGGRAPH [Courses], 2000 */ template struct LoopWeight { - inline SCALAR_TYPE beta(int k) { - return (k>3)?(5.0/8.0 - std::pow((3.0/8.0 + std::cos(2.0*M_PI/SCALAR_TYPE(k))/4.0),2))/SCALAR_TYPE(k):3.0/16.0; - } - - inline SCALAR_TYPE incidentRegular(int) { - return 3.0/8.0; - } - inline SCALAR_TYPE incidentIrregular(int) { - return 3.0/8.0; - } - inline SCALAR_TYPE opposite(int) { - return 1.0/8.0; - } + inline SCALAR_TYPE beta(int k) { + return (k>3)?(5.0/8.0 - std::pow((3.0/8.0 + std::cos(2.0*M_PI/SCALAR_TYPE(k))/4.0),2))/SCALAR_TYPE(k):3.0/16.0; + } + + inline SCALAR_TYPE incidentRegular(int) { + return 3.0/8.0; + } + inline SCALAR_TYPE incidentIrregular(int) { + return 3.0/8.0; + } + inline SCALAR_TYPE opposite(int) { + return 1.0/8.0; + } }; /*! * \brief Modified Loop's weight to optimise continuity. - * + * * See Barthe, L. & Kobbelt, L.: Subdivision scheme tuning around extraordinary vertices. Computer Aided Geometric Design, 2004, 21, 561-583 */ template struct RegularLoopWeight { - inline SCALAR_TYPE beta(int k) { - static SCALAR_TYPE bkPolar[] = { - .32517, - .49954, - .59549, - .625, - .63873, - .64643, - .65127, - .67358, - .68678, - .69908 - }; + inline SCALAR_TYPE beta(int k) { + static SCALAR_TYPE bkPolar[] = { + .32517, + .49954, + .59549, + .625, + .63873, + .64643, + .65127, + .67358, + .68678, + .69908 + }; - return (k<=12)?(1.0-bkPolar[k-3])/k:LoopWeight().beta(k); - } - - inline SCALAR_TYPE incidentRegular(int k) { - return 1.0 - incidentIrregular(k) - opposite(k)*2; - } - inline SCALAR_TYPE incidentIrregular(int k) { - static SCALAR_TYPE bkPolar[] = { - .15658, - .25029, - .34547, - .375, - .38877, - .39644, - .40132, - .42198, - .43423, - .44579 - }; + return (k<=12)?(1.0-bkPolar[k-3])/k:LoopWeight().beta(k); + } - return (k<=12)?bkPolar[k-3]:LoopWeight().incidentIrregular(k); - } - inline SCALAR_TYPE opposite(int k) { - static SCALAR_TYPE bkPolar[] = { - .14427, - .12524, - .11182, - .125, - .14771, - .1768, - .21092, - .20354, - .20505, - .19828 - }; + inline SCALAR_TYPE incidentRegular(int k) { + return 1.0 - incidentIrregular(k) - opposite(k)*2; + } + inline SCALAR_TYPE incidentIrregular(int k) { + static SCALAR_TYPE bkPolar[] = { + .15658, + .25029, + .34547, + .375, + .38877, + .39644, + .40132, + .42198, + .43423, + .44579 + }; - return (k<=12)?bkPolar[k-3]:LoopWeight().opposite(k); - } + return (k<=12)?bkPolar[k-3]:LoopWeight().incidentIrregular(k); + } + inline SCALAR_TYPE opposite(int k) { + static SCALAR_TYPE bkPolar[] = { + .14427, + .12524, + .11182, + .125, + .14771, + .1768, + .21092, + .20354, + .20505, + .19828 + }; + + return (k<=12)?bkPolar[k-3]:LoopWeight().opposite(k); + } }; template struct ContinuityLoopWeight { - inline SCALAR_TYPE beta(int k) { - static SCALAR_TYPE bkPolar[] = { - .32517, - .50033, - .59464, - .625, - .63903, - .67821, - .6866, - .69248, - .69678, - .70014 - }; + inline SCALAR_TYPE beta(int k) { + static SCALAR_TYPE bkPolar[] = { + .32517, + .50033, + .59464, + .625, + .63903, + .67821, + .6866, + .69248, + .69678, + .70014 + }; - return (k<=12)?(1.0-bkPolar[k-3])/k:LoopWeight().beta(k); - } - - inline SCALAR_TYPE incidentRegular(int k) { - return 1.0 - incidentIrregular(k) - opposite(k)*2; - } - inline SCALAR_TYPE incidentIrregular(int k) { - static SCALAR_TYPE bkPolar[] = { - .15658, - .26721, - .33539, - .375, - .36909, - .25579, - .2521, - .24926, - .24706, - .2452 - }; + return (k<=12)?(1.0-bkPolar[k-3])/k:LoopWeight().beta(k); + } - return (k<=12)?bkPolar[k-3]:LoopWeight().incidentIrregular(k); - } - inline SCALAR_TYPE opposite(int k) { - static SCALAR_TYPE bkPolar[] = { - .14427, - .12495, - .11252, - .125, - .14673, - .16074, - .18939, - .2222, - .25894, - .29934 - }; + inline SCALAR_TYPE incidentRegular(int k) { + return 1.0 - incidentIrregular(k) - opposite(k)*2; + } + inline SCALAR_TYPE incidentIrregular(int k) { + static SCALAR_TYPE bkPolar[] = { + .15658, + .26721, + .33539, + .375, + .36909, + .25579, + .2521, + .24926, + .24706, + .2452 + }; - return (k<=12)?bkPolar[k-3]:LoopWeight().opposite(k); - } + return (k<=12)?bkPolar[k-3]:LoopWeight().incidentIrregular(k); + } + inline SCALAR_TYPE opposite(int k) { + static SCALAR_TYPE bkPolar[] = { + .14427, + .12495, + .11252, + .125, + .14673, + .16074, + .18939, + .2222, + .25894, + .29934 + }; + + return (k<=12)?bkPolar[k-3]:LoopWeight().opposite(k); + } }; // Centroid and LS3Projection classes may be pettre placed in an other file. (which one ?) @@ -206,32 +206,32 @@ struct ContinuityLoopWeight { */ template struct Centroid { - typedef typename MESH_TYPE::ScalarType Scalar; - typedef typename MESH_TYPE::CoordType Coord; - typedef LSCALAR_TYPE LScalar; - typedef vcg::Point3 LVector; + typedef typename MESH_TYPE::ScalarType Scalar; + typedef typename MESH_TYPE::CoordType CoordType; + typedef LSCALAR_TYPE LScalar; + typedef vcg::Point3 LVector; - LVector sumP; - LScalar sumW; + LVector sumP; + LScalar sumW; - Centroid() { reset(); } - inline void reset() { - sumP.SetZero(); - sumW = 0.; - } - inline void addVertex(const typename MESH_TYPE::VertexType &v, LScalar w) { - LVector p(v.cP().X(), v.cP().Y(), v.cP().Z()); - sumP += p * w; - sumW += w; - } - inline void project(std::pair &nv) const { - LVector position = sumP / sumW; - nv.first = Coord(position.X(), position.Y(), position.Z()); - } + Centroid() { reset(); } + inline void reset() { + sumP.SetZero(); + sumW = 0.; + } + inline void addVertex(const typename MESH_TYPE::VertexType &v, LScalar w) { + LVector p(v.cP().X(), v.cP().Y(), v.cP().Z()); + sumP += p * w; + sumW += w; + } + inline void project(std::pair &nv) const { + LVector position = sumP / sumW; + nv.first = CoordType(position.X(), position.Y(), position.Z()); + } }; /*! Implementation of the APSS projection for the LS3 scheme. - * + * * See Gael Guennebaud and Marcel Germann and Markus Gross * Dynamic sampling and rendering of algebraic point set surfaces. * Computer Graphics Forum (Proceedings of Eurographics 2008), 2008, 27, 653-662 @@ -241,291 +241,293 @@ struct Centroid { */ template struct LS3Projection { - typedef typename MESH_TYPE::ScalarType Scalar; - typedef typename MESH_TYPE::CoordType Coord; - typedef LSCALAR_TYPE LScalar; - typedef vcg::Point3 LVector; + typedef typename MESH_TYPE::ScalarType Scalar; + typedef typename MESH_TYPE::CoordType CoordType; + typedef LSCALAR_TYPE LScalar; + typedef vcg::Point3 LVector; - Scalar beta; + Scalar beta; - LVector sumP; - LVector sumN; - LScalar sumDotPN; - LScalar sumDotPP; - LScalar sumW; - - inline LS3Projection(Scalar beta = 1.0) : beta(beta) { reset(); } - inline void reset() { - sumP.SetZero(); - sumN.SetZero(); - sumDotPN = 0.; - sumDotPP = 0.; - sumW = 0.; - } - inline void addVertex(const typename MESH_TYPE::VertexType &v, LScalar w) { - LVector p(v.cP().X(), v.cP().Y(), v.cP().Z()); - LVector n(v.cN().X(), v.cN().Y(), v.cN().Z()); + LVector sumP; + LVector sumN; + LScalar sumDotPN; + LScalar sumDotPP; + LScalar sumW; - sumP += p * w; - sumN += n * w; - sumDotPN += w * n.dot(p); - sumDotPP += w * vcg::SquaredNorm(p); - sumW += w; - } - void project(std::pair &nv) const { - LScalar invSumW = Scalar(1)/sumW; - LScalar aux4 = beta * LScalar(0.5) * - (sumDotPN - invSumW*sumP.dot(sumN)) - /(sumDotPP - invSumW*vcg::SquaredNorm(sumP)); - LVector uLinear = (sumN-sumP*(Scalar(2)*aux4))*invSumW; - LScalar uConstant = -invSumW*(uLinear.dot(sumP) + sumDotPP*aux4); - LScalar uQuad = aux4; - LVector orig = sumP*invSumW; + inline LS3Projection(Scalar beta = 1.0) : beta(beta) { reset(); } + inline void reset() { + sumP.SetZero(); + sumN.SetZero(); + sumDotPN = 0.; + sumDotPP = 0.; + sumW = 0.; + } + inline void addVertex(const typename MESH_TYPE::VertexType &v, LScalar w) { + LVector p(v.cP().X(), v.cP().Y(), v.cP().Z()); + LVector n(v.cN().X(), v.cN().Y(), v.cN().Z()); - // finalize - LVector position; - LVector normal; - if (fabs(uQuad)>1e-7) - { - LScalar b = 1./uQuad; - LVector center = uLinear*(-0.5*b); - LScalar radius = sqrt( vcg::SquaredNorm(center) - b*uConstant ); - - normal = orig - center; - normal.Normalize(); - position = center + normal * radius; + sumP += p * w; + sumN += n * w; + sumDotPN += w * n.dot(p); + sumDotPP += w * vcg::SquaredNorm(p); + sumW += w; + } + void project(std::pair &nv) const { + LScalar invSumW = Scalar(1)/sumW; + LScalar aux4 = beta * LScalar(0.5) * + (sumDotPN - invSumW*sumP.dot(sumN)) + /(sumDotPP - invSumW*vcg::SquaredNorm(sumP)); + LVector uLinear = (sumN-sumP*(Scalar(2)*aux4))*invSumW; + LScalar uConstant = -invSumW*(uLinear.dot(sumP) + sumDotPP*aux4); + LScalar uQuad = aux4; + LVector orig = sumP*invSumW; - normal = uLinear + position * (LScalar(2) * uQuad); - normal.Normalize(); - } - else if (uQuad==0.) - { - LScalar s = LScalar(1)/vcg::Norm(uLinear); - assert(!vcg::math::IsNAN(s) && "normal should not have zero len!"); - uLinear *= s; - uConstant *= s; - - normal = uLinear; - position = orig - uLinear * (orig.dot(uLinear) + uConstant); - } - else - { - // normalize the gradient - LScalar f = 1./sqrt(vcg::SquaredNorm(uLinear) - Scalar(4)*uConstant*uQuad); - uConstant *= f; - uLinear *= f; - uQuad *= f; - - // Newton iterations - LVector grad; - LVector dir = uLinear+orig*(2.*uQuad); - LScalar ilg = 1./vcg::Norm(dir); - dir *= ilg; - LScalar ad = uConstant + uLinear.dot(orig) + uQuad * vcg::SquaredNorm(orig); - LScalar delta = -ad*std::min(ilg,1.); - LVector p = orig + dir*delta; - for (int i=0 ; i<2 ; ++i) - { - grad = uLinear+p*(2.*uQuad); - ilg = 1./vcg::Norm(grad); - delta = -(uConstant + uLinear.dot(p) + uQuad * vcg::SquaredNorm(p))*std::min(ilg,1.); - p += dir*delta; - } - position = p; + // finalize + LVector position; + LVector normal; + if (fabs(uQuad)>1e-7) + { + LScalar b = 1./uQuad; + LVector center = uLinear*(-0.5*b); + LScalar radius = sqrt( vcg::SquaredNorm(center) - b*uConstant ); - normal = uLinear + position * (Scalar(2) * uQuad); - normal.Normalize(); - } + normal = orig - center; + normal.Normalize(); + position = center + normal * radius; - nv.first = Coord(position.X(), position.Y(), position.Z()); - nv.second = Coord(normal.X(), normal.Y(), normal.Z()); - } + normal = uLinear + position * (LScalar(2) * uQuad); + normal.Normalize(); + } + else if (uQuad==0.) + { + LScalar s = LScalar(1)/vcg::Norm(uLinear); + assert(!vcg::math::IsNAN(s) && "normal should not have zero len!"); + uLinear *= s; + uConstant *= s; + + normal = uLinear; + position = orig - uLinear * (orig.dot(uLinear) + uConstant); + } + else + { + // normalize the gradient + LScalar f = 1./sqrt(vcg::SquaredNorm(uLinear) - Scalar(4)*uConstant*uQuad); + uConstant *= f; + uLinear *= f; + uQuad *= f; + + // Newton iterations + LVector grad; + LVector dir = uLinear+orig*(2.*uQuad); + LScalar ilg = 1./vcg::Norm(dir); + dir *= ilg; + LScalar ad = uConstant + uLinear.dot(orig) + uQuad * vcg::SquaredNorm(orig); + LScalar delta = -ad*std::min(ilg,1.); + LVector p = orig + dir*delta; + for (int i=0 ; i<2 ; ++i) + { + grad = uLinear+p*(2.*uQuad); + ilg = 1./vcg::Norm(grad); + delta = -(uConstant + uLinear.dot(p) + uQuad * vcg::SquaredNorm(p))*std::min(ilg,1.); + p += dir*delta; + } + position = p; + + normal = uLinear + position * (Scalar(2) * uQuad); + normal.Normalize(); + } + + nv.first = Coord(position.X(), position.Y(), position.Z()); + nv.second = Coord(normal.X(), normal.Y(), normal.Z()); + } }; template, class WEIGHT_TYPE=LoopWeight > struct OddPointLoopGeneric : public std::unary_function , typename MESH_TYPE::VertexType> { typedef METHOD_TYPE Projection; - typedef WEIGHT_TYPE Weight; - typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; - - MESH_TYPE &m; - Projection proj; - Weight weight; - ValenceAttr *valence; - - inline OddPointLoopGeneric(MESH_TYPE &_m, Projection proj = Projection(), Weight weight = Weight()) : - m(_m), proj(proj), weight(weight), valence(0) {} - - void operator()(typename MESH_TYPE::VertexType &nv, face::Pos ep) { - proj.reset(); - - face::Pos he(ep.f,ep.z,ep.f->V(ep.z)); - typename MESH_TYPE::VertexType *l,*r,*u,*d; - l = he.v; - he.FlipV(); - r = he.v; + typedef WEIGHT_TYPE Weight; + typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; + typedef typename MESH_TYPE::CoordType CoordType; - if( tri::HasPerVertexColor(m)) - nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f); + MESH_TYPE &m; + Projection proj; + Weight weight; + ValenceAttr *valence; - if (he.IsBorder()) { - proj.addVertex(*l, 0.5); - proj.addVertex(*r, 0.5); - std::pairpp; - proj.project(pp); - nv.P()=pp.first; - nv.N()=pp.second; - } - else { - he.FlipE(); he.FlipV(); - u = he.v; - he.FlipV(); he.FlipE(); - assert(he.v == r); // back to r - he.FlipF(); he.FlipE(); he.FlipV(); - d = he.v; + inline OddPointLoopGeneric(MESH_TYPE &_m, Projection proj = Projection(), Weight weight = Weight()) : + m(_m), proj(proj), weight(weight), valence(0) {} - if(valence && ((*valence)[l]==6 || (*valence)[r]==6)) { - int extra = ((*valence)[l]==6)?(*valence)[r]:(*valence)[l]; - proj.addVertex(*l, ((*valence)[l]==6)?weight.incidentRegular(extra):weight.incidentIrregular(extra)); - proj.addVertex(*r, ((*valence)[r]==6)?weight.incidentRegular(extra):weight.incidentIrregular(extra)); - proj.addVertex(*u, weight.opposite(extra)); - proj.addVertex(*d, weight.opposite(extra)); - } - // unhandled case that append only at first subdivision step: use Loop's weights - else { - proj.addVertex(*l, 3.0/8.0); - proj.addVertex(*r, 3.0/8.0); - proj.addVertex(*u, 1.0/8.0); - proj.addVertex(*d, 1.0/8.0); - } - std::pairpp; - proj.project(pp); - nv.P()=pp.first; - nv.N()=pp.second; + void operator()(typename MESH_TYPE::VertexType &nv, face::Pos ep) { + proj.reset(); + + face::Pos he(ep.f,ep.z,ep.f->V(ep.z)); + typename MESH_TYPE::VertexType *l,*r,*u,*d; + l = he.v; + he.FlipV(); + r = he.v; + + if( tri::HasPerVertexColor(m)) + nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f); + + if (he.IsBorder()) { + proj.addVertex(*l, 0.5); + proj.addVertex(*r, 0.5); + std::pairpp; + proj.project(pp); + nv.P()=pp.first; + nv.N()=pp.second; + } + else { + he.FlipE(); he.FlipV(); + u = he.v; + he.FlipV(); he.FlipE(); + assert(he.v == r); // back to r + he.FlipF(); he.FlipE(); he.FlipV(); + d = he.v; + + if(valence && ((*valence)[l]==6 || (*valence)[r]==6)) { + int extra = ((*valence)[l]==6)?(*valence)[r]:(*valence)[l]; + proj.addVertex(*l, ((*valence)[l]==6)?weight.incidentRegular(extra):weight.incidentIrregular(extra)); + proj.addVertex(*r, ((*valence)[r]==6)?weight.incidentRegular(extra):weight.incidentIrregular(extra)); + proj.addVertex(*u, weight.opposite(extra)); + proj.addVertex(*d, weight.opposite(extra)); + } + // unhandled case that append only at first subdivision step: use Loop's weights + else { + proj.addVertex(*l, 3.0/8.0); + proj.addVertex(*r, 3.0/8.0); + proj.addVertex(*u, 1.0/8.0); + proj.addVertex(*d, 1.0/8.0); + } + std::pairpp; + proj.project(pp); + nv.P()=pp.first; + nv.N()=pp.second; // proj.project(nv); - } + } - } + } - Color4 WedgeInterp(Color4 &c0, Color4 &c1) - { - Color4 cc; - return cc.lerp(c0,c1,0.5f); - } + Color4 WedgeInterp(Color4 &c0, Color4 &c1) + { + Color4 cc; + return cc.lerp(c0,c1,0.5f); + } - template - TexCoord2 WedgeInterp(TexCoord2 &t0, TexCoord2 &t1) - { - TexCoord2 tmp; - tmp.n()=t0.n(); - tmp.t()=(t0.t()+t1.t())/2.0; - return tmp; - } + template + TexCoord2 WedgeInterp(TexCoord2 &t0, TexCoord2 &t1) + { + TexCoord2 tmp; + tmp.n()=t0.n(); + tmp.t()=(t0.t()+t1.t())/2.0; + return tmp; + } - inline void setValenceAttr(ValenceAttr *valence) { - this->valence = valence; - } + inline void setValenceAttr(ValenceAttr *valence) { + this->valence = valence; + } }; template, class WEIGHT_TYPE=LoopWeight > struct EvenPointLoopGeneric : public std::unary_function , typename MESH_TYPE::VertexType> { - typedef METHOD_TYPE Projection; - typedef WEIGHT_TYPE Weight; - typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; + typedef METHOD_TYPE Projection; + typedef WEIGHT_TYPE Weight; + typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; + typedef typename MESH_TYPE::CoordType CoordType; - Projection proj; - Weight weight; - ValenceAttr *valence; - - inline EvenPointLoopGeneric(Projection proj = Projection(), Weight weight = Weight()) : - proj(proj), weight(weight), valence(0) {} - - void operator()(std::pair &nv, face::Pos ep) { - proj.reset(); - - face::Pos he(ep.f,ep.z,ep.f->V(ep.z)); - typename MESH_TYPE::VertexType *r, *l, *curr; - curr = he.v; - face::Pos heStart = he; + Projection proj; + Weight weight; + ValenceAttr *valence; - // compute valence of this vertex or find a border - int k = 0; - do { - he.NextE(); - k++; - } while(!he.IsBorder() && he != heStart); + inline EvenPointLoopGeneric(Projection proj = Projection(), Weight weight = Weight()) : + proj(proj), weight(weight), valence(0) {} - if (he.IsBorder()) { // Border rule - // consider valence of borders as if they are half+1 of an inner vertex. not perfect, but better than nothing. - if(valence) { - k = 0; - do { - he.NextE(); - k++; - } while(!he.IsBorder()); - (*valence)[he.V()] = std::max(2*(k-1), 3); + void operator()(std::pair &nv, face::Pos ep) { + proj.reset(); + + face::Pos he(ep.f,ep.z,ep.f->V(ep.z)); + typename MESH_TYPE::VertexType *r, *l, *curr; + curr = he.v; + face::Pos heStart = he; + + // compute valence of this vertex or find a border + int k = 0; + do { + he.NextE(); + k++; + } while(!he.IsBorder() && he != heStart); + + if (he.IsBorder()) { // Border rule + // consider valence of borders as if they are half+1 of an inner vertex. not perfect, but better than nothing. + if(valence) { + k = 0; + do { + he.NextE(); + k++; + } while(!he.IsBorder()); + (*valence)[he.V()] = std::max(2*(k-1), 3); // (*valence)[he.V()] = 6; - } - - he.FlipV(); - r = he.v; - he.FlipV(); - he.NextB(); - l = he.v; - - proj.addVertex(*curr, 3.0/4.0); - proj.addVertex(*l, 1.0/8.0); - proj.addVertex(*r, 1.0/8.0); + } + + he.FlipV(); + r = he.v; + he.FlipV(); + he.NextB(); + l = he.v; + + proj.addVertex(*curr, 3.0/4.0); + proj.addVertex(*l, 1.0/8.0); + proj.addVertex(*r, 1.0/8.0); // std::pairpp; - proj.project(nv); + proj.project(nv); // nv.P()=pp.first; // nv.N()=pp.second; // proj.project(nv); - } - else { // Inner rule + } + else { // Inner rule // assert(!he.v->IsB()); border flag no longer updated (useless) - if(valence) - (*valence)[he.V()] = k; - - typename MESH_TYPE::ScalarType beta = weight.beta(k); + if(valence) + (*valence)[he.V()] = k; - proj.addVertex(*curr, 1.0 - (typename MESH_TYPE::ScalarType)(k) * beta); - do { - proj.addVertex(*he.VFlip(), beta); - he.NextE(); - } while(he != heStart); - - proj.project(nv); - } - } // end of operator() + typename MESH_TYPE::ScalarType beta = weight.beta(k); - Color4 WedgeInterp(Color4 &c0, Color4 &c1) - { - Color4 cc; - return cc.lerp(c0,c1,0.5f); - } - Color4b WedgeInterp(Color4b &c0, Color4b &c1) - { - Color4b cc; - cc.lerp(c0,c1,0.5f); - return cc; - } + proj.addVertex(*curr, 1.0 - (typename MESH_TYPE::ScalarType)(k) * beta); + do { + proj.addVertex(*he.VFlip(), beta); + he.NextE(); + } while(he != heStart); - template - TexCoord2 WedgeInterp(TexCoord2 &t0, TexCoord2 &t1) - { - TexCoord2 tmp; - // assert(t0.n()== t1.n()); - tmp.n()=t0.n(); - tmp.t()=(t0.t()+t1.t())/2.0; - return tmp; - } + proj.project(nv); + } + } // end of operator() - inline void setValenceAttr(ValenceAttr *valence) { - this->valence = valence; - } + Color4 WedgeInterp(Color4 &c0, Color4 &c1) + { + Color4 cc; + return cc.lerp(c0,c1,0.5f); + } + Color4b WedgeInterp(Color4b &c0, Color4b &c1) + { + Color4b cc; + cc.lerp(c0,c1,0.5f); + return cc; + } + + template + TexCoord2 WedgeInterp(TexCoord2 &t0, TexCoord2 &t1) + { + TexCoord2 tmp; + // assert(t0.n()== t1.n()); + tmp.n()=t0.n(); + tmp.t()=(t0.t()+t1.t())/2.0; + return tmp; + } + + inline void setValenceAttr(ValenceAttr *valence) { + this->valence = valence; + } }; template @@ -552,73 +554,73 @@ bool RefineOddEven(MESH_TYPE &m, ODD_VERT odd, EVEN_VERT even,float length, */ template bool RefineOddEvenE(MESH_TYPE &m, ODD_VERT odd, EVEN_VERT even, PREDICATE edgePred, - bool RefineSelected=false, CallBackPos *cbOdd = 0, CallBackPos *cbEven = 0) + bool RefineSelected=false, CallBackPos *cbOdd = 0, CallBackPos *cbEven = 0) { - typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; + typedef typename MESH_TYPE::template PerVertexAttributeHandle ValenceAttr; - // momentaneamente le callback sono identiche, almeno cbOdd deve essere passata - cbEven = cbOdd; + // momentaneamente le callback sono identiche, almeno cbOdd deve essere passata + cbEven = cbOdd; - // to mark visited vertices - int evenFlag = MESH_TYPE::VertexType::NewBitFlag(); - for (int i = 0; i < m.vn ; i++ ) { - m.vert[i].ClearUserBit(evenFlag); - } + // to mark visited vertices + int evenFlag = MESH_TYPE::VertexType::NewBitFlag(); + for (int i = 0; i < m.vn ; i++ ) { + m.vert[i].ClearUserBit(evenFlag); + } - int j = 0; + int j = 0; // di texture per wedge (uno per ogni edge) ValenceAttr valence = vcg::tri::Allocator:: template AddPerVertexAttribute(m); - odd.setValenceAttr(&valence); - even.setValenceAttr(&valence); - - // store updated vertices - std::vector updatedList(m.vn, false); - //std::vector newEven(m.vn); - std::vector > newEven(m.vn); + odd.setValenceAttr(&valence); + even.setValenceAttr(&valence); - typename MESH_TYPE::VertexIterator vi; - typename MESH_TYPE::FaceIterator fi; - for (fi = m.face.begin(); fi != m.face.end(); fi++) if(!(*fi).IsD() && (!RefineSelected || (*fi).IsS())){ //itero facce - for (int i = 0; i < 3; i++) { //itero vert - if ( !(*fi).V(i)->IsUserBit(evenFlag) && ! (*fi).V(i)->IsD() ) { - (*fi).V(i)->SetUserBit(evenFlag); - // use face selection, not vertex selection, to be coherent with RefineE - //if (RefineSelected && !(*fi).V(i)->IsS() ) - // break; - face::Posaux (&(*fi),i); - if( tri::HasPerVertexColor(m) ) { - (*fi).V(i)->C().lerp((*fi).V0(i)->C() , (*fi).V1(i)->C(),0.5f); - } + // store updated vertices + std::vector updatedList(m.vn, false); + //std::vector newEven(m.vn); + std::vector > newEven(m.vn); - if (cbEven) { - (*cbEven)(int(100.0f * (float)j / (float)m.fn),"Refining"); - j++; - } - int index = tri::Index(m, (*fi).V(i)); - updatedList[index] = true; - even(newEven[index], aux); - } - } - } - - MESH_TYPE::VertexType::DeleteBitFlag(evenFlag); + typename MESH_TYPE::VertexIterator vi; + typename MESH_TYPE::FaceIterator fi; + for (fi = m.face.begin(); fi != m.face.end(); fi++) if(!(*fi).IsD() && (!RefineSelected || (*fi).IsS())){ //itero facce + for (int i = 0; i < 3; i++) { //itero vert + if ( !(*fi).V(i)->IsUserBit(evenFlag) && ! (*fi).V(i)->IsD() ) { + (*fi).V(i)->SetUserBit(evenFlag); + // use face selection, not vertex selection, to be coherent with RefineE + //if (RefineSelected && !(*fi).V(i)->IsS() ) + // break; + face::Posaux (&(*fi),i); + if( tri::HasPerVertexColor(m) ) { + (*fi).V(i)->C().lerp((*fi).V0(i)->C() , (*fi).V1(i)->C(),0.5f); + } - // Now apply the stored normal and position to the initial vertex set (note that newEven is << m.vert) - RefineE< MESH_TYPE, ODD_VERT > (m, odd, edgePred, RefineSelected, cbOdd); - for(size_t i=0;i (m, odd, edgePred, RefineSelected, cbOdd); + for(size_t i=0;i::DeletePerVertexAttribute(m, valence); - - return true; + + return true; } } // namespace tri