24#ifndef __VCGLIB_REFINE
25#define __VCGLIB_REFINE
29#include <vcg/space/sphere3.h>
30#include <vcg/space/plane3.h>
31#include <vcg/complex/algorithms/clean.h>
32#include <vcg/space/texcoord2.h>
33#include <vcg/space/triangle3.h>
34#include <vcg/complex/algorithms/vertex_interpolation.h>
96const Split SplitTab[8]={
98 {1, {{0,1,2},{0,0,0},{0,0,0},{0,0,0}}, {{0,0},{0,0}}, {{0,1,2},{0,0,0},{0,0,0},{0,0,0}} },
99 {2, {{0,3,2},{3,1,2},{0,0,0},{0,0,0}}, {{0,0},{0,0}}, {{0,3,2},{0,1,3},{0,0,0},{0,0,0}} },
100 {2, {{0,1,4},{0,4,2},{0,0,0},{0,0,0}}, {{0,0},{0,0}}, {{0,1,3},{3,1,2},{0,0,0},{0,0,0}} },
101 {3, {{3,1,4},{0,3,2},{4,2,3},{0,0,0}}, {{0,4},{3,2}}, {{0,1,3},{0,3,2},{1,3,3},{0,0,0}} },
102 {2, {{0,1,5},{5,1,2},{0,0,0},{0,0,0}}, {{0,0},{0,0}}, {{0,3,2},{3,1,2},{0,0,0},{0,0,0}} },
103 {3, {{0,3,5},{3,1,5},{2,5,1},{0,0,0}}, {{3,2},{5,1}}, {{0,3,2},{0,3,3},{2,3,1},{0,0,0}} },
104 {3, {{2,5,4},{0,1,5},{4,5,1},{0,0,0}}, {{0,4},{5,1}}, {{2,3,1},{0,3,2},{3,3,1},{0,0,0}} },
106 {4, {{3,4,5},{0,3,5},{3,1,4},{5,4,2}}, {{0,0},{0,0}}, {{3,3,3},{0,3,2},{0,1,3},{3,1,2}} },
110template <
class MeshType>
113 typedef typename face::Pos<typename MeshType::FaceType> PosType;
114 typedef typename MeshType::VertexType VertexType;
115 void operator()(VertexType &, PosType ){}
125template<
class MESH_TYPE,
class InterpolatorFunctorType = BaseInterpolator< MESH_TYPE> >
128 typedef typename face::Pos<typename MESH_TYPE::FaceType> PosType;
129 typedef typename MESH_TYPE::VertexType VertexType;
132 InterpolatorFunctorType *_intFunc=0) {
138 InterpolatorFunctorType *intFunc;
142 VertexType *V0 = ep.V() ;
143 VertexType *V1 = ep.VFlip() ;
144 if(V0 > V1) std::swap(V1,V0);
146 nv.P()= (V0->P()+V1->P())/2.0;
147 VertexInterpolator<MESH_TYPE>::Lerp(*mp, nv, *V0, *V1, 0.5);
155 return cc.lerp(c0,c1,0.5f);
158 template<
class FL_TYPE>
159 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
161 TexCoord2<FL_TYPE,1> tmp;
162 assert(t0.n()== t1.n());
164 tmp.t()=(t0.t()+t1.t())/2.0;
171template<
class MESH_TYPE>
174 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
176 const typename MESH_TYPE::ScalarType EPS =1e-10;
177 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
178 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
179 typename MESH_TYPE::ScalarType w =n.Norm();
180 if(w<EPS) { nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
return;}
182 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
183 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
184 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
186 typename MESH_TYPE::CoordType nn = ep.f->V1(ep.z)->N() ^ ep.f->V(ep.z)->N();
187 typename MESH_TYPE::CoordType np = n ^ d0;
192 typename MESH_TYPE::CoordType n0=ep.f->V(ep.z)->N() -np*(ep.f->V(ep.z)->N()*np);
194 typename MESH_TYPE::CoordType n1=ep.f->V1(ep.z)->N()-np*(ep.f->V1(ep.z)->N()*np);
195 assert(n1.Norm()>EPS);
197 typename MESH_TYPE::ScalarType cosa0=n0*n;
198 typename MESH_TYPE::ScalarType cosa1=n1*n;
199 if(2-cosa0-cosa1<EPS) {nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
return;}
200 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
201 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
204 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
205 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
206 assert(delta0+delta1<2*d);
207 nv.P()=vp+n*sign*(delta0+delta1)/2.0;
215 return cc.lerp(c0,c1,0.5f);
218 template<
class FL_TYPE>
219 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
221 TexCoord2<FL_TYPE,1> tmp;
222 assert(t0.n()== t1.n());
224 tmp.t()=(t0.t()+t1.t())/2.0;
243template<
class MESH_TYPE>
246 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
249 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
250 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
252 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
253 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
254 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
256 typename MESH_TYPE::ScalarType cosa0=ep.f->V(ep.z)->N()*n;
257 typename MESH_TYPE::ScalarType cosa1=ep.f->V1(ep.z)->N()*n;
258 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
259 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
261 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
262 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
264 return vp+n*(delta0+delta1)/2.0;
275template <
class MESH_TYPE,
class FLT>
281 EdgeLen(FLT threshold) {setThr(threshold);}
282 void setThr(FLT threshold) {squaredThr = threshold*threshold; }
283 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
const
285 return SquaredDistance(ep.V()->P(), ep.VFlip()->P())>squaredThr;
304template <
class VertexPo
inter>
309 ep[0] = ep[1] = ep[2] =
false;
310 vp[0] = vp[1] = vp[2] = NULL;
316template<
class MESH_TYPE,
class MIDPOINT,
class EDGEPRED>
317bool RefineE(MESH_TYPE &m, MIDPOINT &mid, EDGEPRED &ep,
bool RefineSelected=
false, CallBackPos *cb = 0)
320 typedef typename MESH_TYPE::VertexIterator VertexIterator;
321 typedef typename MESH_TYPE::FaceIterator FaceIterator;
322 typedef typename MESH_TYPE::VertexPointer VertexPointer;
323 typedef typename MESH_TYPE::FacePointer FacePointer;
324 typedef typename MESH_TYPE::FaceType FaceType;
325 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
326 assert(tri::HasFFAdjacency(m));
328 typedef face::Pos<FaceType> PosType;
330 int j,NewVertNum=0,NewFaceNum=0;
333 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
338 int PercStep=std::max(1,m.fn/33);
342 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi)
if(!(*fi).IsD())
344 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,
"Refining...");
346 if(RefineSelected && !(*fi).IsS())
continue;
350 if(RD[fi].ep[j])
continue;
352 PosType edgeCur(&*fi,j);
353 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
354 if(!ep(edgeCur))
continue;
356 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
359 assert(edgeCur.IsManifold());
360 if(!edgeCur.IsBorder())
364 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
373 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
380 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
382 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,
"Refining...");
386 if(RefineSelected && !(*fi).IsS())
continue;
389 PosType edgeCur(&*fi,j);
390 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
392 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
394 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
396 if(!edgeCur.IsBorder())
399 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
400 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
408 assert(lastv==m.vert.end());
411 FaceIterator oldendf = lastf;
436 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
438 if(cb && (++step%PercStep)==0)
439 (*cb)(step/PercStep,
"Refining...");
443 vv[3] = RD[fi].vp[0];
444 vv[4] = RD[fi].vp[1];
445 vv[5] = RD[fi].vp[2];
447 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
451 for(i=1;i<SplitTab[ind].TriNum;++i){
452 nf[i]=&*lastf; ++lastf;
453 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
454 nf[i]->ImportData(*fi);
460 if(tri::HasPerWedgeTexCoord(m))
464 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
467 int orgflag = (*fi).Flags();
468 for (i=0; i<SplitTab[ind].TriNum; ++i)
471 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
473 if(tri::HasPerWedgeTexCoord(m))
474 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
476 assert((*nf[i]).V(j)!=0);
477 if(SplitTab[ind].TE[i][j]!=3)
479 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
484 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
485 (*nf[i]).SetFaceEdgeS(j);
487 (*nf[i]).ClearFaceEdgeS(j);
492 (*nf[i]).ClearFaceEdgeS(j);
496 if(SplitTab[ind].TriNum==3 &&
497 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
498 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
500 (*nf[2]).V(1)=(*nf[1]).V(0);
501 (*nf[1]).V(1)=(*nf[2]).V(0);
502 if(tri::HasPerWedgeTexCoord(m)){
503 (*nf[2]).WT(1)=(*nf[1]).WT(0);
504 (*nf[1]).WT(1)=(*nf[2]).WT(0);
507 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
508 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
512 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
513 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
514 (*nf[1]).ClearFaceEdgeS(0);
515 (*nf[2]).ClearFaceEdgeS(0);
519 assert(lastf==m.face.end());
520 assert(!m.vert.empty());
521 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
522 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
523 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
524 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
528 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
536template<
class MESH_TYPE,
class MIDPOINT>
537bool Refine(MESH_TYPE &m, MIDPOINT mid,
typename MESH_TYPE::ScalarType thr=0,
bool RefineSelected=
false, CallBackPos *cb = 0)
539 EdgeLen <MESH_TYPE, typename MESH_TYPE::ScalarType> ep(thr);
540 return RefineE(m,mid,ep,RefineSelected,cb);
566template<
class MESH_TYPE>
572 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
574 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
575 typename MESH_TYPE::CoordType *vl,*vr;
576 typename MESH_TYPE::CoordType *vl0,*vr0;
577 typename MESH_TYPE::CoordType *vu,*vd,*vul,*vur,*vdl,*vdr;
584 VertexInterpolator<MESH_TYPE>::Lerp(m, nv, *ep.f->V(ep.z), *ep.f->V1(ep.z), 0.5);
592 assert(&he.v->P()==vl);
595 nv.P()=((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
599 he.FlipE();he.FlipV();
601 he.FlipF();he.FlipE();he.FlipV();
603 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
605 he.FlipF();he.FlipE();he.FlipV();
607 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
608 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vl);
609 he.FlipE();he.FlipV();
611 he.FlipF();he.FlipE();he.FlipV();
613 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vd);
615 he.FlipF();he.FlipE();he.FlipV();
618 nv.P()=((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
626 return cc.lerp(c0,c1,0.5f);
629 template<
class FL_TYPE>
630 TexCoord2<FL_TYPE,1>
WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
632 TexCoord2<FL_TYPE,1> tmp;
633 assert(t0.n()== t1.n());
635 tmp.t()=(t0.t()+t1.t())/2.0;
649 case 0 :
return ((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
650 case 1 :
return (*vl*6 + *vr*10 + *vu + *vd*3 - *vur - *vdl -*vdr*2 )/16.0;
651 case 2 :
return (*vr*6 + *vl*10 + *vu + *vd*3 - *vul - *vdr -*vdl*2 )/16.0;
652 case 4 :
return (*vr*6 + *vl*10 + *vd + *vu*3 - *vdl - *vur -*vul*2 )/16.0;
653 case 8 :
return (*vl*6 + *vr*10 + *vd + *vu*3 - *vdr - *vul -*vur*2 )/16.0;
654 case 3 :
return (*vl*4 + *vr*4 + *vd*2 + - *vdr - *vdl )/8.0;
655 case 12 :
return (*vl*4 + *vr*4 + *vu*2 + - *vur - *vul )/8.0;
660 return (*vl+ *vr)/2.0;
681template<
class MESH_TYPE>
684 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
686double Rules[11][10] =
691 { .4166666667, -.08333333333 , -.08333333333 },
692 { .375 , .0 , -0.125 , .0 },
693 { .35 , .03090169945 , -.08090169945 , -.08090169945, .03090169945 },
694 { .5 , .125 , -0.0625 , .0 , -0.0625 , 0.125 },
695 { .25 , .1088899050 , -.06042933822 , -.04846056675, -.04846056675, -.06042933822, .1088899050 },
696 { .21875 , .1196383476 , -.03125 , -.05713834763, -.03125 , -.05713834763, -.03125 ,.1196383476 },
697 { .1944444444, .1225409480 , -.00513312590 , -.05555555556, -.03407448880, -.03407448880, -.05555555556, -.00513312590, .1225409480 },
698 { .175 , .1213525492 , .01545084973 , -.04635254918, -.04045084973, -.025 , -.04045084973, -.04635254918, .01545084973, .1213525492 }
701face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
702 typename MESH_TYPE::CoordType *vl,*vr;
707 typename MESH_TYPE::CoordType *vl0,*vr0;
712 assert(&he.v->P()==vl);
715 return ((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
719 bool bl=
false,br=
false;
720 face::Pos<typename MESH_TYPE::FaceType> heStart=he;assert(he.v->P()==*vl);
722 he.FlipE();he.FlipF();
723 if(he.IsBorder()) bl=
true;
725 }
while(he!=heStart);
727 he.FlipV();heStart=he;assert(he.v->P()==*vr);
729 he.FlipE();he.FlipF();
730 if(he.IsBorder()) br=
true;
732 }
while(he!=heStart);
736 typename MESH_TYPE::CoordType newposl=*vl*.75, newposr=*vr*.75;
737 he.FlipV();heStart=he; assert(he.v->P()==*vl);
741 newposl+= he.VFlip()->P() * Rules[kl][i];
742 he.FlipE();he.FlipF();
744 }
while(he!=heStart);
745 i=0;he.FlipV();heStart=he;assert(he.v->P()==*vr);
748 newposr+=he.VFlip()->P()* Rules[kr][i];
749 he.FlipE();he.FlipF();
751 }
while(he!=heStart);
752 if(kr==6)
return newposl;
753 if(kl==6)
return newposr;
754 return newposl+newposr;
783template<
class MESH_TYPE,
class ATTR_TYPE>
788 typedef typename MESH_TYPE::ScalarType ScalarType;
789 typedef typename MESH_TYPE::VertexType VertexType;
790 typedef typename MESH_TYPE::template PerVertexAttributeHandle<ATTR_TYPE> Handle;
797 : mp(_mp), h(_h), thr(_thr) {}
799 void operator()(VertexType &nv,
const face::Pos<typename MESH_TYPE::FaceType> &ep)
801 VertexType *v0 = ep.f->V0(ep.z);
802 VertexType *v1 = ep.f->V1(ep.z);
803 const ATTR_TYPE q0 = h[v0] - thr;
804 const ATTR_TYPE q1 = h[v1] - thr;
808 const ScalarType t = ScalarType(
double(q0) /
double(q0 - q1));
809 const ScalarType s = ScalarType(1) - t;
811 nv.P() = v0->P() * s + v1->P() * t;
813 VertexInterpolator<MESH_TYPE>::Lerp(*mp, nv, *v0, *v1, t);
819 return cc.lerp(c0, c1, 0.5f);
822 template<
class FL_TYPE>
823 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
825 TexCoord2<FL_TYPE,1> tmp;
826 assert(t0.n() == t1.n());
828 tmp.t() = (t0.t() + t1.t()) / 2.0;
833template <
class MESH_TYPE,
class ATTR_TYPE>
837 typedef typename MESH_TYPE::ScalarType ScalarType;
838 typedef typename MESH_TYPE::template PerVertexAttributeHandle<ATTR_TYPE> Handle;
842 ScalarType tolerance;
845 : h(_h), thr(_thr), tolerance(_tolerance) {}
847 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
853 if (!ep.IsManifold())
return false;
854 ATTR_TYPE q0 = h[ep.f->V0(ep.z)] - thr;
855 ATTR_TYPE q1 = h[ep.f->V1(ep.z)] - thr;
856 if (q0 > q1) std::swap(q0, q1);
858 if (q0 * q1 >= 0)
return false;
862 const double pp = double(q0) / double(q0 - q1);
863 if ((fabs(pp) < tolerance) || (fabs(pp) > (1 - tolerance)))
return false;
868template<
class MESH_TYPE>
873 typedef typename MESH_TYPE::ScalarType ScalarType;
880 void operator()(
typename MESH_TYPE::VertexType &nv,
const face::Pos<typename MESH_TYPE::FaceType> &ep){
881 Point3x p0=ep.f->V0(ep.z)->P();
882 Point3x p1=ep.f->V1(ep.z)->P();
883 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
884 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
885 double pp= q0/(q0-q1);
886 nv.P()=p1*pp + p0*(1.0-pp);
893 return cc.lerp(c0,c1,0.5f);
896 template<
class FL_TYPE>
897 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
899 TexCoord2<FL_TYPE,1> tmp;
900 assert(t0.n()== t1.n());
902 tmp.t()=(t0.t()+t1.t())/2.0;
908template <
class MESH_TYPE>
913 typedef typename MESH_TYPE::ScalarType ScalarType;
915 ScalarType tolerance;
916 QualityEdgePredicate(
const ScalarType &thr,ScalarType _tolerance=0.02):thr(thr) {tolerance=_tolerance;}
917 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
919 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
920 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
921 if(q0>q1) std::swap(q0,q1);
922 if ( q0*q1 >= 0)
return false;
924 double pp= q0/(q0-q1);
925 if ((fabs(pp)< tolerance)||(fabs(pp)> (1-tolerance)))
return false;
931template<
class MESH_TYPE>
934 Sphere3<typename MESH_TYPE::ScalarType> sph;
937 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep){
938 Point3x &p0=ep.f->V0(ep.z)->P();
939 Point3x &p1=ep.f->V1(ep.z)->P();
940 nv.P()= sph.c+((p0+p1)/2.0 - sph.c ).Normalize();
946 return cc.lerp(c0,c1,0.5f);
949 template<
class FL_TYPE>
950 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
952 TexCoord2<FL_TYPE,1> tmp;
953 assert(t0.n()== t1.n());
955 tmp.t()=(t0.t()+t1.t())/2.0;
968 if(Distance(sph,p0)>0) {
969 if(Distance(sph,p1)>0)
return false;
972 else if(Distance(sph,p1)<=0)
return false;
977template<
class TRIMESH_TYPE>
980 typename TRIMESH_TYPE::CoordType operator()(
typename TRIMESH_TYPE::FacePointer f){
981 return vcg::Barycenter<typename TRIMESH_TYPE::FaceType>(*f);
989template<
class TRIMESH_TYPE,
class CenterPo
int=CenterPo
intBarycenter <TRIMESH_TYPE> >
993 typedef typename TRIMESH_TYPE::FaceType FaceType;
994 typedef typename TRIMESH_TYPE::VertexType VertexType;
996 static void Apply(FaceType *f,
997 FaceType * f1,FaceType * f2,
998 VertexType * vB, CenterPoint Center)
1000 vB->P() = Center(f);
1003 VertexType *V0,*V1,*V2;
1011 (*f1).V(0) = &(*vB);
1016 (*f2).V(1) = &(*vB);
1019 if(f->HasFFAdjacency())
1022 f->FFp(1)->FFp(f->FFi(1)) = f1;
1023 f->FFp(2)->FFp(f->FFi(2)) = f2;
1026 FaceType * FF0,*FF1,*FF2;
1032 char FFi0,FFi1,FFi2;
1039 (*f).FFp(1) = &(*f1);
1041 (*f).FFp(2) = &(*f2);
1049 (*f1).FFi(1) = FFi1;
1051 (*f1).FFp(2) = &(*f2);
1058 (*f2).FFp(1) = &(*f1);
1062 (*f2).FFi(2) = FFi2;
1067 bool IsFaceEdgeS[3];
1069 for (
size_t i=0;i<3;i++)
1071 IsFaceEdgeS[i]=(*f).IsFaceEdgeS(i);
1072 (*f).ClearFaceEdgeS(i);
1073 (*f1).ClearFaceEdgeS(i);
1074 (*f2).ClearFaceEdgeS(i);
1077 if (IsFaceEdgeS[0])(*f).SetFaceEdgeS(0);
1078 if (IsFaceEdgeS[1])(*f1).SetFaceEdgeS(1);
1079 if (IsFaceEdgeS[2])(*f2).SetFaceEdgeS(2);
1091template <
class MeshType>
1094 typedef typename MeshType::VertexIterator VertexIterator;
1095 typedef typename MeshType::FaceIterator FaceIterator;
1096 typedef typename MeshType::VertexPointer VertexPointer;
1097 typedef typename MeshType::FacePointer FacePointer;
1122 for(
int i=0;i<startFn;++i)
1124 if(!onlySelected || m.face[i].IsS())
1126 FacePointer f0= &m.face[i];
1127 FacePointer f1= &*lastf; ++lastf;
1128 f1->ImportData(*f0);
1129 FacePointer f2= &*lastf; ++lastf;
1130 f2->ImportData(*f0);
1131 FacePointer f3= &*lastf; ++lastf;
1132 f3->ImportData(*f0);
1133 VertexPointer v0 =m.face[i].V(0);
1134 VertexPointer v1 =m.face[i].V(1);
1135 VertexPointer v2 =m.face[i].V(2);
1136 VertexPointer mp01 = &*lastv; ++lastv;
1137 VertexPointer mp12 = &*lastv; ++lastv;
1138 VertexPointer mp02 = &*lastv; ++lastv;
1140 f0->V(0) = v0; f0->V(1) = mp01; f0->V(2) = mp02;
1141 f1->V(0) = v1; f1->V(1) = mp12; f1->V(2) = mp01;
1142 f2->V(0) = v2; f2->V(1) = mp02; f2->V(2) = mp12;
1143 f3->V(0) = mp12; f3->V(1) = mp02; f3->V(2) = mp01;
1144 mp01->P() = (v0>v1) ? (v0->P()+v1->P())/2.0 : (v1->P()+v0->P())/2.0;
1145 mp12->P() = (v1>v2) ? (v1->P()+v2->P())/2.0 : (v2->P()+v1->P())/2.0;
1146 mp02->P() = (v0>v2) ? (v0->P()+v2->P())/2.0 : (v2->P()+v0->P())/2.0;
1147 if(tri::HasPerVertexNormal(m))
1149 mp01->N() = (v0>v1) ? (v0->N()+v1->N()).Normalize() : (v1->N()+v0->N()).Normalize();
1150 mp12->N() = (v1>v2) ? (v1->N()+v2->N()).Normalize() : (v2->N()+v1->N()).Normalize();
1151 mp02->N() = (v0>v2) ? (v0->N()+v2->N()).Normalize() : (v2->N()+v0->N()).Normalize();
1156 printf(
"Vertex unification %i\n",vd);
1158 printf(
"Vertex unref %i\n",vu);
1163template<
class MESH_TYPE,
class EDGEPRED>
1164bool RefineMidpoint(MESH_TYPE &m, EDGEPRED &ep,
bool RefineSelected=
false, CallBackPos *cb = 0)
1167 typedef typename MESH_TYPE::VertexIterator VertexIterator;
1168 typedef typename MESH_TYPE::FaceIterator FaceIterator;
1169 typedef typename MESH_TYPE::VertexPointer VertexPointer;
1170 typedef typename MESH_TYPE::FacePointer FacePointer;
1171 typedef typename MESH_TYPE::FaceType FaceType;
1172 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
1174 assert(tri::HasFFAdjacency(m));
1176 typedef face::Pos<FaceType> PosType;
1178 int j,NewVertNum=0,NewFaceNum=0;
1180 typedef RefinedFaceData<VertexPointer> RFD;
1181 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
1184 MidPoint<MESH_TYPE> mid(&m);
1187 int PercStep=std::max(1,m.fn/33);
1191 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi)
if(!(*fi).IsD())
1193 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,
"Refining...");
1195 if(RefineSelected && !(*fi).IsS())
continue;
1199 if(RD[fi].ep[j])
continue;
1201 PosType edgeCur(&*fi,j);
1202 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1203 if(!ep(edgeCur))
continue;
1205 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
1208 PosType start = edgeCur;
1209 if (!edgeCur.IsBorder())
1214 edgeCur.F()->SetV();
1215 RD[edgeCur.F()].ep[edgeCur.E()] =
true;
1217 }
while (edgeCur != start);
1226 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
1233 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
1235 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,
"Refining...");
1239 if(RefineSelected && !(*fi).IsS())
continue;
1242 PosType edgeCur(&*fi,j);
1243 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1245 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
1247 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1248 mid(*lastv,edgeCur);
1249 PosType start = edgeCur;
1250 if (!edgeCur.IsBorder())
1255 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
1256 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1257 }
while (edgeCur != start);
1265 assert(lastv==m.vert.end());
1268 FaceIterator oldendf = lastf;
1285 VertexPointer vv[6];
1290 TexCoordType wtt[6];
1293 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
1295 if(cb && (++step%PercStep)==0)
1296 (*cb)(step/PercStep,
"Refining...");
1300 vv[3] = RD[fi].vp[0];
1301 vv[4] = RD[fi].vp[1];
1302 vv[5] = RD[fi].vp[2];
1304 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
1308 for(i=1;i<SplitTab[ind].TriNum;++i){
1309 nf[i]=&*lastf; ++lastf;
1310 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
1311 nf[i]->ImportData(*fi);
1316 if(tri::HasPerWedgeTexCoord(m))
1320 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
1323 int orgflag = (*fi).Flags();
1324 for (i=0; i<SplitTab[ind].TriNum; ++i)
1327 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
1329 if(tri::HasPerWedgeTexCoord(m))
1330 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
1332 assert((*nf[i]).V(j)!=0);
1333 if(SplitTab[ind].TE[i][j]!=3)
1335 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
1340 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
1341 (*nf[i]).SetFaceEdgeS(j);
1343 (*nf[i]).ClearFaceEdgeS(j);
1348 (*nf[i]).ClearFaceEdgeS(j);
1352 if(SplitTab[ind].TriNum==3 &&
1353 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
1354 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
1356 (*nf[2]).V(1)=(*nf[1]).V(0);
1357 (*nf[1]).V(1)=(*nf[2]).V(0);
1358 if(tri::HasPerWedgeTexCoord(m)){
1359 (*nf[2]).WT(1)=(*nf[1]).WT(0);
1360 (*nf[1]).WT(1)=(*nf[2]).WT(0);
1363 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
1364 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
1368 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
1369 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
1370 (*nf[1]).ClearFaceEdgeS(0);
1371 (*nf[2]).ClearFaceEdgeS(0);
1375 assert(lastf==m.face.end());
1376 assert(!m.vert.empty());
1377 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
1378 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
1379 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
1380 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
1384 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
Class to safely add and delete elements in a mesh.
Definition: allocate.h:97
static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater< VertexPointer > &pu)
Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to ...
Definition: allocate.h:195
static FaceIterator AddFaces(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:621
static int RemoveDuplicateVertex(MeshType &m, bool RemoveDegenerateFlag=true)
Definition: clean.h:206
static int RemoveUnreferencedVertex(MeshType &m, bool DeleteVertexFlag=true)
Definition: clean.h:394
Triangle split Simple templated function for splitting a triangle with a internal point....
Definition: refine.h:991
static void FaceBorderFromFF(MeshType &m)
Compute the border flags for the faces using the Face-Face Topology.
Definition: flag.h:170
static size_t FaceCount(const MeshType &m)
This function returns the number of selected faces.
Definition: selection.h:280
static void FaceFace(MeshType &m)
Update the Face-Face topological relation by allowing to retrieve for each face what other faces shar...
Definition: topology.h:395
void TrivialMidPointRefine(MeshType &m, bool onlySelected=false)
Trivial function for 1->4 triangle split.
Definition: refine.h:1092
Color4< typename MESH_TYPE::ScalarType > WedgeInterp(Color4< typename MESH_TYPE::ScalarType > &c0, Color4< typename MESH_TYPE::ScalarType > &c1)
Aggiunte in modo grezzo le due wedge interp.
Definition: refine.h:623
void operator()(VertexType &nv, PosType ep)
This callback is called to fill up.
Definition: refine.h:140