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>
95 const Split SplitTab[8]={
97 {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}} },
98 {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}} },
99 {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}} },
100 {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}} },
101 {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}} },
102 {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}} },
103 {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}} },
105 {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}} },
109 template <
class MeshType>
112 typedef typename face::Pos<typename MeshType::FaceType> PosType;
113 typedef typename MeshType::VertexType VertexType;
114 void operator()(VertexType &, PosType ){}
124 template<
class MESH_TYPE,
class InterpolatorFunctorType = BaseInterpolator< MESH_TYPE> >
127 typedef typename face::Pos<typename MESH_TYPE::FaceType> PosType;
128 typedef typename MESH_TYPE::VertexType VertexType;
131 InterpolatorFunctorType *_intFunc=0) {
137 InterpolatorFunctorType *intFunc;
141 VertexType *V0 = ep.V() ;
142 VertexType *V1 = ep.VFlip() ;
143 if(V0 > V1) std::swap(V1,V0);
145 nv.P()= (V0->P()+V1->P())/2.0;
147 if( tri::HasPerVertexNormal(*mp))
148 nv.N()= (V0->N()+V1->N()).normalized();
150 if( tri::HasPerVertexColor(*mp))
151 nv.C().lerp(V0->C(),V1->C(),.5f);
153 if( tri::HasPerVertexQuality(*mp))
154 nv.Q() = (V0->Q()+V1->Q()) / 2.0;
156 if( tri::HasPerVertexTexCoord(*mp))
157 nv.T().P() = (V0->T().P()+V1->T().P()) / 2.0;
165 return cc.lerp(c0,c1,0.5f);
168 template<
class FL_TYPE>
169 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
171 TexCoord2<FL_TYPE,1> tmp;
172 assert(t0.n()== t1.n());
174 tmp.t()=(t0.t()+t1.t())/2.0;
181 template<
class MESH_TYPE>
184 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
186 const typename MESH_TYPE::ScalarType EPS =1e-10;
187 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
188 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
189 typename MESH_TYPE::ScalarType w =n.Norm();
190 if(w<EPS) { nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
return;}
192 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
193 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
194 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
196 typename MESH_TYPE::CoordType nn = ep.f->V1(ep.z)->N() ^ ep.f->V(ep.z)->N();
197 typename MESH_TYPE::CoordType np = n ^ d0;
202 typename MESH_TYPE::CoordType n0=ep.f->V(ep.z)->N() -np*(ep.f->V(ep.z)->N()*np);
204 typename MESH_TYPE::CoordType n1=ep.f->V1(ep.z)->N()-np*(ep.f->V1(ep.z)->N()*np);
205 assert(n1.Norm()>EPS);
207 typename MESH_TYPE::ScalarType cosa0=n0*n;
208 typename MESH_TYPE::ScalarType cosa1=n1*n;
209 if(2-cosa0-cosa1<EPS) {nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
return;}
210 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
211 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
214 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
215 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
216 assert(delta0+delta1<2*d);
217 nv.P()=vp+n*sign*(delta0+delta1)/2.0;
225 return cc.lerp(c0,c1,0.5f);
228 template<
class FL_TYPE>
229 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
231 TexCoord2<FL_TYPE,1> tmp;
232 assert(t0.n()== t1.n());
234 tmp.t()=(t0.t()+t1.t())/2.0;
253 template<
class MESH_TYPE>
256 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
259 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
260 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
262 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
263 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
264 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
266 typename MESH_TYPE::ScalarType cosa0=ep.f->V(ep.z)->N()*n;
267 typename MESH_TYPE::ScalarType cosa1=ep.f->V1(ep.z)->N()*n;
268 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
269 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
271 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
272 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
274 return vp+n*(delta0+delta1)/2.0;
285 template <
class MESH_TYPE,
class FLT>
291 EdgeLen(FLT threshold) {setThr(threshold);}
292 void setThr(FLT threshold) {squaredThr = threshold*threshold; }
293 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
const
295 return SquaredDistance(ep.V()->P(), ep.VFlip()->P())>squaredThr;
314 template <
class VertexPo
inter>
319 ep[0] = ep[1] = ep[2] =
false;
320 vp[0] = vp[1] = vp[2] = NULL;
326 template<
class MESH_TYPE,
class MIDPOINT,
class EDGEPRED>
327 bool RefineE(MESH_TYPE &m, MIDPOINT &mid, EDGEPRED &ep,
bool RefineSelected=
false, CallBackPos *cb = 0)
330 typedef typename MESH_TYPE::VertexIterator VertexIterator;
331 typedef typename MESH_TYPE::FaceIterator FaceIterator;
332 typedef typename MESH_TYPE::VertexPointer VertexPointer;
333 typedef typename MESH_TYPE::FacePointer FacePointer;
334 typedef typename MESH_TYPE::FaceType FaceType;
335 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
336 assert(tri::HasFFAdjacency(m));
338 typedef face::Pos<FaceType> PosType;
340 int j,NewVertNum=0,NewFaceNum=0;
343 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
348 int PercStep=std::max(1,m.fn/33);
352 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi)
if(!(*fi).IsD())
354 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,
"Refining...");
356 if(RefineSelected && !(*fi).IsS())
continue;
360 if(RD[fi].ep[j])
continue;
362 PosType edgeCur(&*fi,j);
363 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
364 if(!ep(edgeCur))
continue;
366 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
369 assert(edgeCur.IsManifold());
370 if(!edgeCur.IsBorder())
374 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
383 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
390 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
392 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,
"Refining...");
396 if(RefineSelected && !(*fi).IsS())
continue;
399 PosType edgeCur(&*fi,j);
400 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
402 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
404 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
406 if(!edgeCur.IsBorder())
409 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
410 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
418 assert(lastv==m.vert.end());
421 FaceIterator oldendf = lastf;
447 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
449 if(cb && (++step%PercStep)==0)
450 (*cb)(step/PercStep,
"Refining...");
454 vv[3] = RD[fi].vp[0];
455 vv[4] = RD[fi].vp[1];
456 vv[5] = RD[fi].vp[2];
458 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
462 for(i=1;i<SplitTab[ind].TriNum;++i){
463 nf[i]=&*lastf; ++lastf; fca++;
464 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
465 nf[i]->ImportData(*fi);
471 if(tri::HasPerWedgeTexCoord(m))
475 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
478 int orgflag = (*fi).Flags();
479 for (i=0; i<SplitTab[ind].TriNum; ++i)
482 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
484 if(tri::HasPerWedgeTexCoord(m))
485 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
487 assert((*nf[i]).V(j)!=0);
488 if(SplitTab[ind].TE[i][j]!=3)
490 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
495 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
496 (*nf[i]).SetFaceEdgeS(j);
498 (*nf[i]).ClearFaceEdgeS(j);
503 (*nf[i]).ClearFaceEdgeS(j);
507 if(SplitTab[ind].TriNum==3 &&
508 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
509 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
511 (*nf[2]).V(1)=(*nf[1]).V(0);
512 (*nf[1]).V(1)=(*nf[2]).V(0);
513 if(tri::HasPerWedgeTexCoord(m)){
514 (*nf[2]).WT(1)=(*nf[1]).WT(0);
515 (*nf[1]).WT(1)=(*nf[2]).WT(0);
518 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
519 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
523 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
524 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
525 (*nf[1]).ClearFaceEdgeS(0);
526 (*nf[2]).ClearFaceEdgeS(0);
530 assert(lastf==m.face.end());
531 assert(!m.vert.empty());
532 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
533 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
534 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
535 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
539 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
547 template<
class MESH_TYPE,
class MIDPOINT>
548 bool Refine(MESH_TYPE &m, MIDPOINT mid,
typename MESH_TYPE::ScalarType thr=0,
bool RefineSelected=
false, CallBackPos *cb = 0)
550 EdgeLen <MESH_TYPE, typename MESH_TYPE::ScalarType> ep(thr);
551 return RefineE(m,mid,ep,RefineSelected,cb);
577 template<
class MESH_TYPE>
583 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
585 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
586 typename MESH_TYPE::CoordType *vl,*vr;
587 typename MESH_TYPE::CoordType *vl0,*vr0;
588 typename MESH_TYPE::CoordType *vu,*vd,*vul,*vur,*vdl,*vdr;
593 if( tri::HasPerVertexColor(m))
594 nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
602 assert(&he.v->P()==vl);
605 nv.P()=((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
609 he.FlipE();he.FlipV();
611 he.FlipF();he.FlipE();he.FlipV();
613 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
615 he.FlipF();he.FlipE();he.FlipV();
617 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
618 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vl);
619 he.FlipE();he.FlipV();
621 he.FlipF();he.FlipE();he.FlipV();
623 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vd);
625 he.FlipF();he.FlipE();he.FlipV();
628 nv.P()=((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
636 return cc.lerp(c0,c1,0.5f);
639 template<
class FL_TYPE>
640 TexCoord2<FL_TYPE,1>
WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
642 TexCoord2<FL_TYPE,1> tmp;
643 assert(t0.n()== t1.n());
645 tmp.t()=(t0.t()+t1.t())/2.0;
659 case 0 :
return ((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
660 case 1 :
return (*vl*6 + *vr*10 + *vu + *vd*3 - *vur - *vdl -*vdr*2 )/16.0;
661 case 2 :
return (*vr*6 + *vl*10 + *vu + *vd*3 - *vul - *vdr -*vdl*2 )/16.0;
662 case 4 :
return (*vr*6 + *vl*10 + *vd + *vu*3 - *vdl - *vur -*vul*2 )/16.0;
663 case 8 :
return (*vl*6 + *vr*10 + *vd + *vu*3 - *vdr - *vul -*vur*2 )/16.0;
664 case 3 :
return (*vl*4 + *vr*4 + *vd*2 + - *vdr - *vdl )/8.0;
665 case 12 :
return (*vl*4 + *vr*4 + *vu*2 + - *vur - *vul )/8.0;
670 return (*vl+ *vr)/2.0;
691 template<
class MESH_TYPE>
694 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
696 double Rules[11][10] =
701 { .4166666667, -.08333333333 , -.08333333333 },
702 { .375 , .0 , -0.125 , .0 },
703 { .35 , .03090169945 , -.08090169945 , -.08090169945, .03090169945 },
704 { .5 , .125 , -0.0625 , .0 , -0.0625 , 0.125 },
705 { .25 , .1088899050 , -.06042933822 , -.04846056675, -.04846056675, -.06042933822, .1088899050 },
706 { .21875 , .1196383476 , -.03125 , -.05713834763, -.03125 , -.05713834763, -.03125 ,.1196383476 },
707 { .1944444444, .1225409480 , -.00513312590 , -.05555555556, -.03407448880, -.03407448880, -.05555555556, -.00513312590, .1225409480 },
708 { .175 , .1213525492 , .01545084973 , -.04635254918, -.04045084973, -.025 , -.04045084973, -.04635254918, .01545084973, .1213525492 }
711 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
712 typename MESH_TYPE::CoordType *vl,*vr;
717 typename MESH_TYPE::CoordType *vl0,*vr0;
722 assert(&he.v->P()==vl);
725 return ((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
729 bool bl=
false,br=
false;
730 face::Pos<typename MESH_TYPE::FaceType> heStart=he;assert(he.v->P()==*vl);
732 he.FlipE();he.FlipF();
733 if(he.IsBorder()) bl=
true;
735 }
while(he!=heStart);
737 he.FlipV();heStart=he;assert(he.v->P()==*vr);
739 he.FlipE();he.FlipF();
740 if(he.IsBorder()) br=
true;
742 }
while(he!=heStart);
746 typename MESH_TYPE::CoordType newposl=*vl*.75, newposr=*vr*.75;
747 he.FlipV();heStart=he; assert(he.v->P()==*vl);
751 newposl+= he.VFlip()->P() * Rules[kl][i];
752 he.FlipE();he.FlipF();
754 }
while(he!=heStart);
755 i=0;he.FlipV();heStart=he;assert(he.v->P()==*vr);
758 newposr+=he.VFlip()->P()* Rules[kr][i];
759 he.FlipE();he.FlipF();
761 }
while(he!=heStart);
762 if(kr==6)
return newposl;
763 if(kl==6)
return newposr;
764 return newposl+newposr;
782 template<
class MESH_TYPE>
787 typedef typename MESH_TYPE::ScalarType ScalarType;
794 void operator()(
typename MESH_TYPE::VertexType &nv,
const face::Pos<typename MESH_TYPE::FaceType> &ep){
795 Point3x p0=ep.f->V0(ep.z)->P();
796 Point3x p1=ep.f->V1(ep.z)->P();
797 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
798 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
799 double pp= q0/(q0-q1);
800 nv.P()=p1*pp + p0*(1.0-pp);
807 return cc.lerp(c0,c1,0.5f);
810 template<
class FL_TYPE>
811 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
813 TexCoord2<FL_TYPE,1> tmp;
814 assert(t0.n()== t1.n());
816 tmp.t()=(t0.t()+t1.t())/2.0;
822 template <
class MESH_TYPE>
827 typedef typename MESH_TYPE::ScalarType ScalarType;
829 ScalarType tolerance;
830 QualityEdgePredicate(
const ScalarType &thr,ScalarType _tolerance=0.02):thr(thr) {tolerance=_tolerance;}
831 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
833 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
834 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
835 if(q0>q1) std::swap(q0,q1);
836 if ( q0*q1 >= 0)
return false;
838 double pp= q0/(q0-q1);
839 if ((fabs(pp)< tolerance)||(fabs(pp)> (1-tolerance)))
return false;
845 template<
class MESH_TYPE>
848 Sphere3<typename MESH_TYPE::ScalarType> sph;
851 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep){
852 Point3x &p0=ep.f->V0(ep.z)->P();
853 Point3x &p1=ep.f->V1(ep.z)->P();
854 nv.P()= sph.c+((p0+p1)/2.0 - sph.c ).Normalize();
860 return cc.lerp(c0,c1,0.5f);
863 template<
class FL_TYPE>
864 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
866 TexCoord2<FL_TYPE,1> tmp;
867 assert(t0.n()== t1.n());
869 tmp.t()=(t0.t()+t1.t())/2.0;
882 if(Distance(sph,p0)>0) {
883 if(Distance(sph,p1)>0)
return false;
886 else if(Distance(sph,p1)<=0)
return false;
891 template<
class TRIMESH_TYPE>
894 typename TRIMESH_TYPE::CoordType operator()(
typename TRIMESH_TYPE::FacePointer f){
895 return vcg::Barycenter<typename TRIMESH_TYPE::FaceType>(*f);
903 template<
class TRIMESH_TYPE,
class CenterPo
int=CenterPo
intBarycenter <TRIMESH_TYPE> >
907 typedef typename TRIMESH_TYPE::FaceType FaceType;
908 typedef typename TRIMESH_TYPE::VertexType VertexType;
910 static void Apply(FaceType *f,
911 FaceType * f1,FaceType * f2,
912 VertexType * vB, CenterPoint Center)
917 VertexType *V0,*V1,*V2;
933 if(f->HasFFAdjacency())
936 f->FFp(1)->FFp(f->FFi(1)) = f1;
937 f->FFp(2)->FFp(f->FFi(2)) = f2;
940 FaceType * FF0,*FF1,*FF2;
953 (*f).FFp(1) = &(*f1);
955 (*f).FFp(2) = &(*f2);
965 (*f1).FFp(2) = &(*f2);
972 (*f2).FFp(1) = &(*f1);
983 for (
size_t i=0;i<3;i++)
985 IsFaceEdgeS[i]=(*f).IsFaceEdgeS(i);
986 (*f).ClearFaceEdgeS(i);
987 (*f1).ClearFaceEdgeS(i);
988 (*f2).ClearFaceEdgeS(i);
991 if (IsFaceEdgeS[0])(*f).SetFaceEdgeS(0);
992 if (IsFaceEdgeS[1])(*f1).SetFaceEdgeS(1);
993 if (IsFaceEdgeS[2])(*f2).SetFaceEdgeS(2);
998 template <
class MeshType>
999 void TrivialMidPointRefine(MeshType & m)
1001 typedef typename MeshType::VertexIterator VertexIterator;
1002 typedef typename MeshType::FaceIterator FaceIterator;
1003 typedef typename MeshType::VertexPointer VertexPointer;
1004 typedef typename MeshType::FacePointer FacePointer;
1024 for(
int i=0;i<startFn;++i)
1026 FacePointer f0= &m.face[i];
1027 FacePointer f1= &*lastf; ++lastf;
1028 FacePointer f2= &*lastf; ++lastf;
1029 FacePointer f3= &*lastf; ++lastf;
1030 VertexPointer v0 =m.face[i].V(0);
1031 VertexPointer v1 =m.face[i].V(1);
1032 VertexPointer v2 =m.face[i].V(2);
1033 VertexPointer mp01 = &*lastv; ++lastv;
1034 VertexPointer mp12 = &*lastv; ++lastv;
1035 VertexPointer mp02 = &*lastv; ++lastv;
1037 f0->V(0) = v0; f0->V(1) = mp01; f0->V(2) = mp02;
1038 f1->V(0) = v1; f1->V(1) = mp12; f1->V(2) = mp01;
1039 f2->V(0) = v2; f2->V(1) = mp02; f2->V(2) = mp12;
1040 f3->V(0) = mp12; f3->V(1) = mp02; f3->V(2) = mp01;
1041 mp01->P() = (v0>v1) ? (v0->P()+v1->P())/2.0 : (v1->P()+v0->P())/2.0;
1042 mp12->P() = (v1>v2) ? (v1->P()+v2->P())/2.0 : (v2->P()+v1->P())/2.0;
1043 mp02->P() = (v0>v2) ? (v0->P()+v2->P())/2.0 : (v2->P()+v0->P())/2.0;
1047 printf(
"Vertex unification %i\n",vd);
1049 printf(
"Vertex unref %i\n",vu);
1050 Allocator<MeshType>::CompactEveryVector(m);
1054 template<
class MESH_TYPE,
class EDGEPRED>
1055 bool RefineMidpoint(MESH_TYPE &m, EDGEPRED &ep,
bool RefineSelected=
false, CallBackPos *cb = 0)
1058 typedef typename MESH_TYPE::VertexIterator VertexIterator;
1059 typedef typename MESH_TYPE::FaceIterator FaceIterator;
1060 typedef typename MESH_TYPE::VertexPointer VertexPointer;
1061 typedef typename MESH_TYPE::FacePointer FacePointer;
1062 typedef typename MESH_TYPE::FaceType FaceType;
1063 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
1065 assert(tri::HasFFAdjacency(m));
1067 typedef face::Pos<FaceType> PosType;
1069 int j,NewVertNum=0,NewFaceNum=0;
1071 typedef RefinedFaceData<VertexPointer> RFD;
1072 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
1073 HandleType RD = tri::Allocator<MESH_TYPE>:: template AddPerFaceAttribute<RFD> (m,std::string(
"RefineData"));
1075 MidPoint<MESH_TYPE> mid(&m);
1078 int PercStep=std::max(1,m.fn/33);
1082 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi)
if(!(*fi).IsD())
1084 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,
"Refining...");
1086 if(RefineSelected && !(*fi).IsS())
continue;
1090 if(RD[fi].ep[j])
continue;
1092 PosType edgeCur(&*fi,j);
1093 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1094 if(!ep(edgeCur))
continue;
1096 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
1099 PosType start = edgeCur;
1100 if (!edgeCur.IsBorder())
1105 edgeCur.F()->SetV();
1106 RD[edgeCur.F()].ep[edgeCur.E()] =
true;
1108 }
while (edgeCur != start);
1117 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
1124 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
1126 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,
"Refining...");
1130 if(RefineSelected && !(*fi).IsS())
continue;
1133 PosType edgeCur(&*fi,j);
1134 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1136 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
1138 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1139 mid(*lastv,edgeCur);
1140 PosType start = edgeCur;
1141 if (!edgeCur.IsBorder())
1146 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
1147 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1148 }
while (edgeCur != start);
1156 assert(lastv==m.vert.end());
1159 FaceIterator oldendf = lastf;
1176 VertexPointer vv[6];
1181 TexCoordType wtt[6];
1185 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
1187 if(cb && (++step%PercStep)==0)
1188 (*cb)(step/PercStep,
"Refining...");
1192 vv[3] = RD[fi].vp[0];
1193 vv[4] = RD[fi].vp[1];
1194 vv[5] = RD[fi].vp[2];
1196 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
1200 for(i=1;i<SplitTab[ind].TriNum;++i){
1201 nf[i]=&*lastf; ++lastf; fca++;
1202 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
1203 nf[i]->ImportData(*fi);
1208 if(tri::HasPerWedgeTexCoord(m))
1212 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
1215 int orgflag = (*fi).Flags();
1216 for (i=0; i<SplitTab[ind].TriNum; ++i)
1219 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
1221 if(tri::HasPerWedgeTexCoord(m))
1222 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
1224 assert((*nf[i]).V(j)!=0);
1225 if(SplitTab[ind].TE[i][j]!=3)
1227 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
1232 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
1233 (*nf[i]).SetFaceEdgeS(j);
1235 (*nf[i]).ClearFaceEdgeS(j);
1240 (*nf[i]).ClearFaceEdgeS(j);
1244 if(SplitTab[ind].TriNum==3 &&
1245 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
1246 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
1248 (*nf[2]).V(1)=(*nf[1]).V(0);
1249 (*nf[1]).V(1)=(*nf[2]).V(0);
1250 if(tri::HasPerWedgeTexCoord(m)){
1251 (*nf[2]).WT(1)=(*nf[1]).WT(0);
1252 (*nf[1]).WT(1)=(*nf[2]).WT(0);
1255 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
1256 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
1260 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
1261 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
1262 (*nf[1]).ClearFaceEdgeS(0);
1263 (*nf[2]).ClearFaceEdgeS(0);
1267 assert(lastf==m.face.end());
1268 assert(!m.vert.empty());
1269 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
1270 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
1271 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
1272 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
1276 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:189
static FaceIterator AddFaces(MeshType &m, size_t n)
Function to add n faces to the mesh. First wrapper, with no parameters.
Definition: allocate.h:615
static int RemoveDuplicateVertex(MeshType &m, bool RemoveDegenerateFlag=true)
Definition: clean.h:206
static int RemoveUnreferencedVertex(MeshType &m, bool DeleteVertexFlag=true)
Definition: clean.h:396
Triangle split Simple templated function for splitting a triangle with a internal point....
Definition: refine.h:905
static void FaceBorderFromFF(MeshType &m)
Compute the border flags for the faces using the Face-Face Topology.
Definition: flag.h:170
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:397
Definition: namespaces.dox:6
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:633
void operator()(VertexType &nv, PosType ep)
This callback is called to fill up.
Definition: refine.h:139