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;
446 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
448 if(cb && (++step%PercStep)==0)
449 (*cb)(step/PercStep,
"Refining...");
453 vv[3] = RD[fi].vp[0];
454 vv[4] = RD[fi].vp[1];
455 vv[5] = RD[fi].vp[2];
457 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
461 for(i=1;i<SplitTab[ind].TriNum;++i){
462 nf[i]=&*lastf; ++lastf;
463 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
464 nf[i]->ImportData(*fi);
470 if(tri::HasPerWedgeTexCoord(m))
474 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
477 int orgflag = (*fi).Flags();
478 for (i=0; i<SplitTab[ind].TriNum; ++i)
481 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
483 if(tri::HasPerWedgeTexCoord(m))
484 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
486 assert((*nf[i]).V(j)!=0);
487 if(SplitTab[ind].TE[i][j]!=3)
489 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
494 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
495 (*nf[i]).SetFaceEdgeS(j);
497 (*nf[i]).ClearFaceEdgeS(j);
502 (*nf[i]).ClearFaceEdgeS(j);
506 if(SplitTab[ind].TriNum==3 &&
507 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
508 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
510 (*nf[2]).V(1)=(*nf[1]).V(0);
511 (*nf[1]).V(1)=(*nf[2]).V(0);
512 if(tri::HasPerWedgeTexCoord(m)){
513 (*nf[2]).WT(1)=(*nf[1]).WT(0);
514 (*nf[1]).WT(1)=(*nf[2]).WT(0);
517 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
518 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
522 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
523 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
524 (*nf[1]).ClearFaceEdgeS(0);
525 (*nf[2]).ClearFaceEdgeS(0);
529 assert(lastf==m.face.end());
530 assert(!m.vert.empty());
531 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
532 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
533 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
534 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
538 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
546 template<
class MESH_TYPE,
class MIDPOINT>
547 bool Refine(MESH_TYPE &m, MIDPOINT mid,
typename MESH_TYPE::ScalarType thr=0,
bool RefineSelected=
false, CallBackPos *cb = 0)
549 EdgeLen <MESH_TYPE, typename MESH_TYPE::ScalarType> ep(thr);
550 return RefineE(m,mid,ep,RefineSelected,cb);
576 template<
class MESH_TYPE>
582 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
584 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
585 typename MESH_TYPE::CoordType *vl,*vr;
586 typename MESH_TYPE::CoordType *vl0,*vr0;
587 typename MESH_TYPE::CoordType *vu,*vd,*vul,*vur,*vdl,*vdr;
592 if( tri::HasPerVertexColor(m))
593 nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
601 assert(&he.v->P()==vl);
604 nv.P()=((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
608 he.FlipE();he.FlipV();
610 he.FlipF();he.FlipE();he.FlipV();
612 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
614 he.FlipF();he.FlipE();he.FlipV();
616 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
617 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vl);
618 he.FlipE();he.FlipV();
620 he.FlipF();he.FlipE();he.FlipV();
622 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vd);
624 he.FlipF();he.FlipE();he.FlipV();
627 nv.P()=((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
635 return cc.lerp(c0,c1,0.5f);
638 template<
class FL_TYPE>
639 TexCoord2<FL_TYPE,1>
WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
641 TexCoord2<FL_TYPE,1> tmp;
642 assert(t0.n()== t1.n());
644 tmp.t()=(t0.t()+t1.t())/2.0;
658 case 0 :
return ((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
659 case 1 :
return (*vl*6 + *vr*10 + *vu + *vd*3 - *vur - *vdl -*vdr*2 )/16.0;
660 case 2 :
return (*vr*6 + *vl*10 + *vu + *vd*3 - *vul - *vdr -*vdl*2 )/16.0;
661 case 4 :
return (*vr*6 + *vl*10 + *vd + *vu*3 - *vdl - *vur -*vul*2 )/16.0;
662 case 8 :
return (*vl*6 + *vr*10 + *vd + *vu*3 - *vdr - *vul -*vur*2 )/16.0;
663 case 3 :
return (*vl*4 + *vr*4 + *vd*2 + - *vdr - *vdl )/8.0;
664 case 12 :
return (*vl*4 + *vr*4 + *vu*2 + - *vur - *vul )/8.0;
669 return (*vl+ *vr)/2.0;
690 template<
class MESH_TYPE>
693 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
695 double Rules[11][10] =
700 { .4166666667, -.08333333333 , -.08333333333 },
701 { .375 , .0 , -0.125 , .0 },
702 { .35 , .03090169945 , -.08090169945 , -.08090169945, .03090169945 },
703 { .5 , .125 , -0.0625 , .0 , -0.0625 , 0.125 },
704 { .25 , .1088899050 , -.06042933822 , -.04846056675, -.04846056675, -.06042933822, .1088899050 },
705 { .21875 , .1196383476 , -.03125 , -.05713834763, -.03125 , -.05713834763, -.03125 ,.1196383476 },
706 { .1944444444, .1225409480 , -.00513312590 , -.05555555556, -.03407448880, -.03407448880, -.05555555556, -.00513312590, .1225409480 },
707 { .175 , .1213525492 , .01545084973 , -.04635254918, -.04045084973, -.025 , -.04045084973, -.04635254918, .01545084973, .1213525492 }
710 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
711 typename MESH_TYPE::CoordType *vl,*vr;
716 typename MESH_TYPE::CoordType *vl0,*vr0;
721 assert(&he.v->P()==vl);
724 return ((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
728 bool bl=
false,br=
false;
729 face::Pos<typename MESH_TYPE::FaceType> heStart=he;assert(he.v->P()==*vl);
731 he.FlipE();he.FlipF();
732 if(he.IsBorder()) bl=
true;
734 }
while(he!=heStart);
736 he.FlipV();heStart=he;assert(he.v->P()==*vr);
738 he.FlipE();he.FlipF();
739 if(he.IsBorder()) br=
true;
741 }
while(he!=heStart);
745 typename MESH_TYPE::CoordType newposl=*vl*.75, newposr=*vr*.75;
746 he.FlipV();heStart=he; assert(he.v->P()==*vl);
750 newposl+= he.VFlip()->P() * Rules[kl][i];
751 he.FlipE();he.FlipF();
753 }
while(he!=heStart);
754 i=0;he.FlipV();heStart=he;assert(he.v->P()==*vr);
757 newposr+=he.VFlip()->P()* Rules[kr][i];
758 he.FlipE();he.FlipF();
760 }
while(he!=heStart);
761 if(kr==6)
return newposl;
762 if(kl==6)
return newposr;
763 return newposl+newposr;
781 template<
class MESH_TYPE>
786 typedef typename MESH_TYPE::ScalarType ScalarType;
793 void operator()(
typename MESH_TYPE::VertexType &nv,
const face::Pos<typename MESH_TYPE::FaceType> &ep){
794 Point3x p0=ep.f->V0(ep.z)->P();
795 Point3x p1=ep.f->V1(ep.z)->P();
796 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
797 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
798 double pp= q0/(q0-q1);
799 nv.P()=p1*pp + p0*(1.0-pp);
806 return cc.lerp(c0,c1,0.5f);
809 template<
class FL_TYPE>
810 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
812 TexCoord2<FL_TYPE,1> tmp;
813 assert(t0.n()== t1.n());
815 tmp.t()=(t0.t()+t1.t())/2.0;
821 template <
class MESH_TYPE>
826 typedef typename MESH_TYPE::ScalarType ScalarType;
828 ScalarType tolerance;
829 QualityEdgePredicate(
const ScalarType &thr,ScalarType _tolerance=0.02):thr(thr) {tolerance=_tolerance;}
830 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
832 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
833 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
834 if(q0>q1) std::swap(q0,q1);
835 if ( q0*q1 >= 0)
return false;
837 double pp= q0/(q0-q1);
838 if ((fabs(pp)< tolerance)||(fabs(pp)> (1-tolerance)))
return false;
844 template<
class MESH_TYPE>
847 Sphere3<typename MESH_TYPE::ScalarType> sph;
850 void operator()(
typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep){
851 Point3x &p0=ep.f->V0(ep.z)->P();
852 Point3x &p1=ep.f->V1(ep.z)->P();
853 nv.P()= sph.c+((p0+p1)/2.0 - sph.c ).Normalize();
859 return cc.lerp(c0,c1,0.5f);
862 template<
class FL_TYPE>
863 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
865 TexCoord2<FL_TYPE,1> tmp;
866 assert(t0.n()== t1.n());
868 tmp.t()=(t0.t()+t1.t())/2.0;
881 if(Distance(sph,p0)>0) {
882 if(Distance(sph,p1)>0)
return false;
885 else if(Distance(sph,p1)<=0)
return false;
890 template<
class TRIMESH_TYPE>
893 typename TRIMESH_TYPE::CoordType operator()(
typename TRIMESH_TYPE::FacePointer f){
894 return vcg::Barycenter<typename TRIMESH_TYPE::FaceType>(*f);
902 template<
class TRIMESH_TYPE,
class CenterPo
int=CenterPo
intBarycenter <TRIMESH_TYPE> >
906 typedef typename TRIMESH_TYPE::FaceType FaceType;
907 typedef typename TRIMESH_TYPE::VertexType VertexType;
909 static void Apply(FaceType *f,
910 FaceType * f1,FaceType * f2,
911 VertexType * vB, CenterPoint Center)
916 VertexType *V0,*V1,*V2;
932 if(f->HasFFAdjacency())
935 f->FFp(1)->FFp(f->FFi(1)) = f1;
936 f->FFp(2)->FFp(f->FFi(2)) = f2;
939 FaceType * FF0,*FF1,*FF2;
952 (*f).FFp(1) = &(*f1);
954 (*f).FFp(2) = &(*f2);
964 (*f1).FFp(2) = &(*f2);
971 (*f2).FFp(1) = &(*f1);
982 for (
size_t i=0;i<3;i++)
984 IsFaceEdgeS[i]=(*f).IsFaceEdgeS(i);
985 (*f).ClearFaceEdgeS(i);
986 (*f1).ClearFaceEdgeS(i);
987 (*f2).ClearFaceEdgeS(i);
990 if (IsFaceEdgeS[0])(*f).SetFaceEdgeS(0);
991 if (IsFaceEdgeS[1])(*f1).SetFaceEdgeS(1);
992 if (IsFaceEdgeS[2])(*f2).SetFaceEdgeS(2);
997 template <
class MeshType>
998 void TrivialMidPointRefine(MeshType & m)
1000 typedef typename MeshType::VertexIterator VertexIterator;
1001 typedef typename MeshType::FaceIterator FaceIterator;
1002 typedef typename MeshType::VertexPointer VertexPointer;
1003 typedef typename MeshType::FacePointer FacePointer;
1023 for(
int i=0;i<startFn;++i)
1025 FacePointer f0= &m.face[i];
1026 FacePointer f1= &*lastf; ++lastf;
1027 f1->ImportData(*f0);
1028 FacePointer f2= &*lastf; ++lastf;
1029 f2->ImportData(*f0);
1030 FacePointer f3= &*lastf; ++lastf;
1031 f3->ImportData(*f0);
1032 VertexPointer v0 =m.face[i].V(0);
1033 VertexPointer v1 =m.face[i].V(1);
1034 VertexPointer v2 =m.face[i].V(2);
1035 VertexPointer mp01 = &*lastv; ++lastv;
1036 VertexPointer mp12 = &*lastv; ++lastv;
1037 VertexPointer mp02 = &*lastv; ++lastv;
1039 f0->V(0) = v0; f0->V(1) = mp01; f0->V(2) = mp02;
1040 f1->V(0) = v1; f1->V(1) = mp12; f1->V(2) = mp01;
1041 f2->V(0) = v2; f2->V(1) = mp02; f2->V(2) = mp12;
1042 f3->V(0) = mp12; f3->V(1) = mp02; f3->V(2) = mp01;
1043 mp01->P() = (v0>v1) ? (v0->P()+v1->P())/2.0 : (v1->P()+v0->P())/2.0;
1044 mp12->P() = (v1>v2) ? (v1->P()+v2->P())/2.0 : (v2->P()+v1->P())/2.0;
1045 mp02->P() = (v0>v2) ? (v0->P()+v2->P())/2.0 : (v2->P()+v0->P())/2.0;
1049 printf(
"Vertex unification %i\n",vd);
1051 printf(
"Vertex unref %i\n",vu);
1052 Allocator<MeshType>::CompactEveryVector(m);
1056 template<
class MESH_TYPE,
class EDGEPRED>
1057 bool RefineMidpoint(MESH_TYPE &m, EDGEPRED &ep,
bool RefineSelected=
false, CallBackPos *cb = 0)
1060 typedef typename MESH_TYPE::VertexIterator VertexIterator;
1061 typedef typename MESH_TYPE::FaceIterator FaceIterator;
1062 typedef typename MESH_TYPE::VertexPointer VertexPointer;
1063 typedef typename MESH_TYPE::FacePointer FacePointer;
1064 typedef typename MESH_TYPE::FaceType FaceType;
1065 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
1067 assert(tri::HasFFAdjacency(m));
1069 typedef face::Pos<FaceType> PosType;
1071 int j,NewVertNum=0,NewFaceNum=0;
1073 typedef RefinedFaceData<VertexPointer> RFD;
1074 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
1075 HandleType RD = tri::Allocator<MESH_TYPE>:: template AddPerFaceAttribute<RFD> (m,std::string(
"RefineData"));
1077 MidPoint<MESH_TYPE> mid(&m);
1080 int PercStep=std::max(1,m.fn/33);
1084 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi)
if(!(*fi).IsD())
1086 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,
"Refining...");
1088 if(RefineSelected && !(*fi).IsS())
continue;
1092 if(RD[fi].ep[j])
continue;
1094 PosType edgeCur(&*fi,j);
1095 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1096 if(!ep(edgeCur))
continue;
1098 RD[edgeCur.F()].ep[edgeCur.E()]=
true;
1101 PosType start = edgeCur;
1102 if (!edgeCur.IsBorder())
1107 edgeCur.F()->SetV();
1108 RD[edgeCur.F()].ep[edgeCur.E()] =
true;
1110 }
while (edgeCur != start);
1119 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
1126 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
1128 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,
"Refining...");
1132 if(RefineSelected && !(*fi).IsS())
continue;
1135 PosType edgeCur(&*fi,j);
1136 if(RefineSelected && ! edgeCur.FFlip()->IsS())
continue;
1138 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
1140 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1141 mid(*lastv,edgeCur);
1142 PosType start = edgeCur;
1143 if (!edgeCur.IsBorder())
1148 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
1149 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
1150 }
while (edgeCur != start);
1158 assert(lastv==m.vert.end());
1161 FaceIterator oldendf = lastf;
1178 VertexPointer vv[6];
1183 TexCoordType wtt[6];
1186 for(fi=m.face.begin();fi!=oldendf;++fi)
if(!(*fi).IsD())
1188 if(cb && (++step%PercStep)==0)
1189 (*cb)(step/PercStep,
"Refining...");
1193 vv[3] = RD[fi].vp[0];
1194 vv[4] = RD[fi].vp[1];
1195 vv[5] = RD[fi].vp[2];
1197 int ind = ((vv[3] != NULL) ? 1 : 0) + ((vv[4] != NULL) ? 2 : 0) + ((vv[5] != NULL) ? 4 : 0);
1201 for(i=1;i<SplitTab[ind].TriNum;++i){
1202 nf[i]=&*lastf; ++lastf;
1203 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
1204 nf[i]->ImportData(*fi);
1209 if(tri::HasPerWedgeTexCoord(m))
1213 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
1216 int orgflag = (*fi).Flags();
1217 for (i=0; i<SplitTab[ind].TriNum; ++i)
1220 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
1222 if(tri::HasPerWedgeTexCoord(m))
1223 (*nf[i]).WT(j) = wtt[SplitTab[ind].TV[i][j]];
1225 assert((*nf[i]).V(j)!=0);
1226 if(SplitTab[ind].TE[i][j]!=3)
1228 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
1233 if(orgflag & (MESH_TYPE::FaceType::FACEEDGESEL0<<(SplitTab[ind].TE[i][j])))
1234 (*nf[i]).SetFaceEdgeS(j);
1236 (*nf[i]).ClearFaceEdgeS(j);
1241 (*nf[i]).ClearFaceEdgeS(j);
1245 if(SplitTab[ind].TriNum==3 &&
1246 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
1247 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
1249 (*nf[2]).V(1)=(*nf[1]).V(0);
1250 (*nf[1]).V(1)=(*nf[2]).V(0);
1251 if(tri::HasPerWedgeTexCoord(m)){
1252 (*nf[2]).WT(1)=(*nf[1]).WT(0);
1253 (*nf[1]).WT(1)=(*nf[2]).WT(0);
1256 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1);
else (*nf[2]).ClearB(1);
1257 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1);
else (*nf[1]).ClearB(1);
1261 if((*nf[1]).IsFaceEdgeS(0)) (*nf[2]).SetFaceEdgeS(1);
else (*nf[2]).ClearFaceEdgeS(1);
1262 if((*nf[2]).IsFaceEdgeS(0)) (*nf[1]).SetFaceEdgeS(1);
else (*nf[1]).ClearFaceEdgeS(1);
1263 (*nf[1]).ClearFaceEdgeS(0);
1264 (*nf[2]).ClearFaceEdgeS(0);
1268 assert(lastf==m.face.end());
1269 assert(!m.vert.empty());
1270 for(fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()){
1271 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
1272 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
1273 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
1277 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:904
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:395
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:632
void operator()(VertexType &nv, PosType ep)
This callback is called to fill up.
Definition: refine.h:139