00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_REFINE
00025 #define __VCGLIB_REFINE
00026
00027 #include <functional>
00028 #include <map>
00029 #include <vcg/space/sphere3.h>
00030 #include <vcg/space/plane3.h>
00031 #include <vcg/simplex/face/pos.h>
00032 #include <vcg/simplex/face/topology.h>
00033 #include <vcg/complex/algorithms/update/topology.h>
00034 #include <vcg/complex/algorithms/update/flag.h>
00035 #include <vcg/complex/algorithms/clean.h>
00036 #include <vcg/space/texcoord2.h>
00037 #include <vcg/space/triangle3.h>
00038
00039 namespace vcg{
00040 namespace tri{
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 class Split {
00089 public:
00090 int TriNum;
00091 int TV[4][3];
00092
00093
00094 int swap[2][2];
00095 int TE[4][3];
00096
00097 };
00098
00099 const Split SplitTab[8]={
00100
00101 {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}} },
00102 {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}} },
00103 {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}} },
00104 {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}} },
00105 {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}} },
00106 {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}} },
00107 {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}} },
00108
00109 {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}} },
00110 };
00111
00112
00113 template <class MeshType>
00114 struct BaseInterpolator
00115 {
00116 typedef typename face::Pos<typename MeshType::FaceType> PosType;
00117 typedef typename MeshType::VertexType VertexType;
00118 void operator()(VertexType &, PosType ){}
00119 };
00120
00121
00122
00123
00124
00125
00126
00127
00128 template<class MESH_TYPE, class InterpolatorFunctorType = BaseInterpolator< MESH_TYPE> >
00129 struct MidPoint : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType >
00130 {
00131 typedef typename face::Pos<typename MESH_TYPE::FaceType> PosType;
00132 typedef typename MESH_TYPE::VertexType VertexType;
00133
00134 MidPoint(MESH_TYPE *_mp,
00135 InterpolatorFunctorType *_intFunc=0) {
00136 mp=_mp;
00137 intFunc =_intFunc;
00138 }
00139
00140 MESH_TYPE *mp;
00141 InterpolatorFunctorType *intFunc;
00142
00143 void operator()(VertexType &nv, PosType ep){
00144 assert(mp);
00145 VertexType *V0 = ep.V() ;
00146 VertexType *V1 = ep.VFlip() ;
00147 if(V0 > V1) std::swap(V1,V0);
00148
00149 nv.P()= (V0->P()+V1->P())/2.0;
00150
00151 if( tri::HasPerVertexNormal(*mp))
00152 nv.N()= (V0->N()+V1->N()).normalized();
00153
00154 if( tri::HasPerVertexColor(*mp))
00155 nv.C().lerp(V0->C(),V1->C(),.5f);
00156
00157 if( tri::HasPerVertexQuality(*mp))
00158 nv.Q() = (V0->Q()+V1->Q()) / 2.0;
00159
00160 if( tri::HasPerVertexTexCoord(*mp))
00161 nv.T().P() = (V0->T().P()+V1->T().P()) / 2.0;
00162 if(intFunc)
00163 (*intFunc)(nv,ep);
00164 }
00165
00166 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00167 {
00168 Color4<typename MESH_TYPE::ScalarType> cc;
00169 return cc.lerp(c0,c1,0.5f);
00170 }
00171
00172 template<class FL_TYPE>
00173 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00174 {
00175 TexCoord2<FL_TYPE,1> tmp;
00176 assert(t0.n()== t1.n());
00177 tmp.n()=t0.n();
00178 tmp.t()=(t0.t()+t1.t())/2.0;
00179 return tmp;
00180 }
00181 };
00182
00183
00184
00185 template<class MESH_TYPE>
00186 struct MidPointArc : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00187 {
00188 void operator()(typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
00189 {
00190 const typename MESH_TYPE::ScalarType EPS =1e-10;
00191 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
00192 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
00193 typename MESH_TYPE::ScalarType w =n.Norm();
00194 if(w<EPS) { nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0; return;}
00195 n/=w;
00196 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
00197 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
00198 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
00199
00200 typename MESH_TYPE::CoordType nn = ep.f->V1(ep.z)->N() ^ ep.f->V(ep.z)->N();
00201 typename MESH_TYPE::CoordType np = n ^ d0;
00202 np.Normalize();
00203 double sign=1;
00204 if(np*nn<0) sign=-1;
00205
00206 typename MESH_TYPE::CoordType n0=ep.f->V(ep.z)->N() -np*(ep.f->V(ep.z)->N()*np);
00207 n0.Normalize();
00208 typename MESH_TYPE::CoordType n1=ep.f->V1(ep.z)->N()-np*(ep.f->V1(ep.z)->N()*np);
00209 assert(n1.Norm()>EPS);
00210 n1.Normalize();
00211 typename MESH_TYPE::ScalarType cosa0=n0*n;
00212 typename MESH_TYPE::ScalarType cosa1=n1*n;
00213 if(2-cosa0-cosa1<EPS) {nv.P()=(ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;return;}
00214 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
00215 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
00216 assert(1+cosa0>EPS);
00217 assert(1+cosa1>EPS);
00218 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
00219 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
00220 assert(delta0+delta1<2*d);
00221 nv.P()=vp+n*sign*(delta0+delta1)/2.0;
00222 return ;
00223 }
00224
00225
00226 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00227 {
00228 Color4<typename MESH_TYPE::ScalarType> cc;
00229 return cc.lerp(c0,c1,0.5f);
00230 }
00231
00232 template<class FL_TYPE>
00233 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00234 {
00235 TexCoord2<FL_TYPE,1> tmp;
00236 assert(t0.n()== t1.n());
00237 tmp.n()=t0.n();
00238 tmp.t()=(t0.t()+t1.t())/2.0;
00239 return tmp;
00240 }
00241
00242 };
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 template<class MESH_TYPE>
00258 struct MidPointArcNaive : public std::unary_function< face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00259 {
00260 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
00261 {
00262
00263 typename MESH_TYPE::CoordType vp = (ep.f->V(ep.z)->P()+ep.f->V1(ep.z)->P())/2.0;
00264 typename MESH_TYPE::CoordType n = (ep.f->V(ep.z)->N()+ep.f->V1(ep.z)->N())/2.0;
00265 n.Normalize();
00266 typename MESH_TYPE::CoordType d0 = ep.f->V(ep.z)->P() - vp;
00267 typename MESH_TYPE::CoordType d1 = ep.f->V1(ep.z)->P()- vp;
00268 typename MESH_TYPE::ScalarType d=Distance(ep.f->V(ep.z)->P(),ep.f->V1(ep.z)->P())/2.0;
00269
00270 typename MESH_TYPE::ScalarType cosa0=ep.f->V(ep.z)->N()*n;
00271 typename MESH_TYPE::ScalarType cosa1=ep.f->V1(ep.z)->N()*n;
00272 typename MESH_TYPE::ScalarType cosb0=(d0*n)/d;
00273 typename MESH_TYPE::ScalarType cosb1=(d1*n)/d;
00274
00275 typename MESH_TYPE::ScalarType delta0=d*(cosb0 +sqrt( ((1-cosb0*cosb0)*(1-cosa0))/(1+cosa0)) );
00276 typename MESH_TYPE::ScalarType delta1=d*(cosb1 +sqrt( ((1-cosb1*cosb1)*(1-cosa1))/(1+cosa1)) );
00277
00278 return vp+n*(delta0+delta1)/2.0;
00279 }
00280 };
00281
00282
00283
00284
00285
00286
00287
00288
00289 template <class MESH_TYPE, class FLT>
00290 class EdgeLen
00291 {
00292 FLT squaredThr;
00293 public:
00294 EdgeLen(){};
00295 EdgeLen(FLT threshold) {setThr(threshold);}
00296 void setThr(FLT threshold) {squaredThr = threshold*threshold; }
00297 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep) const
00298 {
00299 return SquaredDistance(ep.V()->P(), ep.VFlip()->P())>squaredThr;
00300 }
00301 };
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 template <class VertexPointer>
00319 class RefinedFaceData
00320 {
00321 public:
00322 RefinedFaceData(){
00323 ep[0]=0;ep[1]=0;ep[2]=0;
00324 vp[0]=0;vp[1]=0;vp[2]=0;
00325 }
00326 bool ep[3];
00327 VertexPointer vp[3];
00328 };
00329
00330 template<class MESH_TYPE,class MIDPOINT, class EDGEPRED>
00331 bool RefineE(MESH_TYPE &m, MIDPOINT &mid, EDGEPRED &ep,bool RefineSelected=false, CallBackPos *cb = 0)
00332 {
00333
00334 typedef typename MESH_TYPE::VertexIterator VertexIterator;
00335 typedef typename MESH_TYPE::FaceIterator FaceIterator;
00336 typedef typename MESH_TYPE::VertexPointer VertexPointer;
00337 typedef typename MESH_TYPE::FacePointer FacePointer;
00338 typedef typename MESH_TYPE::FaceType FaceType;
00339 typedef typename MESH_TYPE::FaceType::TexCoordType TexCoordType;
00340 assert(tri::HasFFAdjacency(m));
00341 tri::UpdateFlags<MESH_TYPE>::FaceBorderFromFF(m);
00342 typedef face::Pos<FaceType> PosType;
00343
00344 int j,NewVertNum=0,NewFaceNum=0;
00345
00346 typedef RefinedFaceData<VertexPointer> RFD;
00347 typedef typename MESH_TYPE :: template PerFaceAttributeHandle<RFD> HandleType;
00348 HandleType RD = tri::Allocator<MESH_TYPE>:: template AddPerFaceAttribute<RFD> (m,std::string("RefineData"));
00349
00350
00351 int step=0;
00352 int PercStep=std::max(1,m.fn/33);
00353
00354
00355 FaceIterator fi;
00356 for(fi=m.face.begin(),j=0;fi!=m.face.end();++fi) if(!(*fi).IsD())
00357 {
00358 if(cb && (++step%PercStep)==0) (*cb)(step/PercStep,"Refining...");
00359
00360 if(RefineSelected && !(*fi).IsS()) continue;
00361
00362 for(j=0;j<3;j++)
00363 {
00364 if(RD[fi].ep[j]) continue;
00365
00366 PosType edgeCur(&*fi,j);
00367 if(RefineSelected && ! edgeCur.FFlip()->IsS()) continue;
00368 if(!ep(edgeCur)) continue;
00369
00370 RD[edgeCur.F()].ep[edgeCur.E()]=true;
00371 ++NewFaceNum;
00372 ++NewVertNum;
00373 assert(edgeCur.IsManifold());
00374 if(!edgeCur.IsBorder())
00375 {
00376 edgeCur.FlipF();
00377 edgeCur.F()->SetV();
00378 RD[edgeCur.F()].ep[edgeCur.E()]=true;
00379 ++NewFaceNum;
00380 }
00381 }
00382
00383 }
00384
00385 if(NewVertNum ==0 )
00386 {
00387 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
00388 return false;
00389 }
00390 VertexIterator lastv = tri::Allocator<MESH_TYPE>::AddVertices(m,NewVertNum);
00391
00392
00393
00394 for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
00395 {
00396 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,"Refining...");
00397 for(j=0;j<3;j++)
00398 {
00399
00400 if(RefineSelected && !(*fi).IsS()) continue;
00401 for(j=0;j<3;j++)
00402 {
00403 PosType edgeCur(&*fi,j);
00404 if(RefineSelected && ! edgeCur.FFlip()->IsS()) continue;
00405
00406 if( RD[edgeCur.F()].ep[edgeCur.E()] && RD[edgeCur.F()].vp[edgeCur.E()] ==0 )
00407 {
00408 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
00409 mid(*lastv,edgeCur);
00410 if(!edgeCur.IsBorder())
00411 {
00412 edgeCur.FlipF();
00413 assert(RD[edgeCur.F()].ep[edgeCur.E()]);
00414 RD[edgeCur.F()].vp[edgeCur.E()] = &*lastv;
00415 }
00416 ++lastv;
00417 }
00418 }
00419 }
00420 }
00421
00422 assert(lastv==m.vert.end());
00423
00424 FaceIterator lastf = tri::Allocator<MESH_TYPE>::AddFaces(m,NewFaceNum);
00425 FaceIterator oldendf = lastf;
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 VertexPointer vv[6];
00443
00444
00445 FacePointer nf[4];
00446
00447 TexCoordType wtt[6];
00448
00449
00450 int fca=0,fcn =0;
00451 for(fi=m.face.begin();fi!=oldendf;++fi) if(!(*fi).IsD())
00452 {
00453 if(cb && (++step%PercStep)==0)(*cb)(step/PercStep,"Refining...");
00454 fcn++;
00455 vv[0]=(*fi).V(0);
00456 vv[1]=(*fi).V(1);
00457 vv[2]=(*fi).V(2);
00458 vv[3] = RD[fi].vp[0];
00459 vv[4] = RD[fi].vp[1];
00460 vv[5] = RD[fi].vp[2];
00461
00462 int ind=((&*vv[3])?1:0)+((&*vv[4])?2:0)+((&*vv[5])?4:0);
00463
00464 nf[0]=&*fi;
00465 int i;
00466 for(i=1;i<SplitTab[ind].TriNum;++i){
00467 nf[i]=&*lastf; ++lastf; fca++;
00468 if(RefineSelected || (*fi).IsS()) (*nf[i]).SetS();
00469 nf[i]->ImportData(*fi);
00470
00471
00472 }
00473
00474
00475 if(tri::HasPerWedgeTexCoord(m))
00476 for(i=0;i<3;++i) {
00477 wtt[i]=(*fi).WT(i);
00478 wtt[3+i]=mid.WedgeInterp((*fi).WT(i),(*fi).WT((i+1)%3));
00479 }
00480
00481 int orgflag= (*fi).Flags();
00482 for(i=0;i<SplitTab[ind].TriNum;++i)
00483 for(j=0;j<3;++j){
00484 (*nf[i]).V(j)=&*vv[SplitTab[ind].TV[i][j]];
00485
00486 if(tri::HasPerWedgeTexCoord(m))
00487 (*nf[i]).WT(j)=wtt[SplitTab[ind].TV[i][j]];
00488
00489 assert((*nf[i]).V(j)!=0);
00490 if(SplitTab[ind].TE[i][j]!=3){
00491 if(orgflag & (MESH_TYPE::FaceType::BORDER0<<(SplitTab[ind].TE[i][j])))
00492 (*nf[i]).SetB(j);
00493 else
00494 (*nf[i]).ClearB(j);
00495 }
00496 else (*nf[i]).ClearB(j);
00497 }
00498
00499 if(SplitTab[ind].TriNum==3 &&
00500 SquaredDistance(vv[SplitTab[ind].swap[0][0]]->P(),vv[SplitTab[ind].swap[0][1]]->P()) <
00501 SquaredDistance(vv[SplitTab[ind].swap[1][0]]->P(),vv[SplitTab[ind].swap[1][1]]->P()) )
00502 {
00503 (*nf[2]).V(1)=(*nf[1]).V(0);
00504 (*nf[1]).V(1)=(*nf[2]).V(0);
00505 if(tri::HasPerWedgeTexCoord(m)){
00506 (*nf[2]).WT(1)=(*nf[1]).WT(0);
00507 (*nf[1]).WT(1)=(*nf[2]).WT(0);
00508 }
00509
00510 if((*nf[1]).IsB(0)) (*nf[2]).SetB(1); else (*nf[2]).ClearB(1);
00511 if((*nf[2]).IsB(0)) (*nf[1]).SetB(1); else (*nf[1]).ClearB(1);
00512 (*nf[1]).ClearB(0);
00513 (*nf[2]).ClearB(0);
00514 }
00515 }
00516
00517 assert(lastf==m.face.end());
00518 assert(!m.vert.empty());
00519 for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()){
00520 assert((*fi).V(0)>=&*m.vert.begin() && (*fi).V(0)<=&m.vert.back() );
00521 assert((*fi).V(1)>=&*m.vert.begin() && (*fi).V(1)<=&m.vert.back() );
00522 assert((*fi).V(2)>=&*m.vert.begin() && (*fi).V(2)<=&m.vert.back() );
00523 }
00524 tri::UpdateTopology<MESH_TYPE>::FaceFace(m);
00525
00526 tri::Allocator<MESH_TYPE> :: template DeletePerFaceAttribute<RefinedFaceData<VertexPointer> > (m,RD);
00527
00528 return true;
00529 }
00530
00531
00532
00533
00534 template<class MESH_TYPE,class MIDPOINT>
00535 bool Refine(MESH_TYPE &m, MIDPOINT mid, typename MESH_TYPE::ScalarType thr=0,bool RefineSelected=false, CallBackPos *cb = 0)
00536 {
00537 EdgeLen <MESH_TYPE, typename MESH_TYPE::ScalarType> ep(thr);
00538 return RefineE(m,mid,ep,RefineSelected,cb);
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 template<class MESH_TYPE>
00565 struct MidPointButterfly : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00566 {
00567 MESH_TYPE &m;
00568 MidPointButterfly(MESH_TYPE &_m):m(_m){}
00569
00570 void operator()(typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep)
00571 {
00572 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
00573 typename MESH_TYPE::CoordType *vl,*vr;
00574 typename MESH_TYPE::CoordType *vl0,*vr0;
00575 typename MESH_TYPE::CoordType *vu,*vd,*vul,*vur,*vdl,*vdr;
00576 vl=&he.v->P();
00577 he.FlipV();
00578 vr=&he.v->P();
00579
00580 if( tri::HasPerVertexColor(m))
00581 nv.C().lerp(ep.f->V(ep.z)->C(),ep.f->V1(ep.z)->C(),.5f);
00582
00583 if(he.IsBorder())
00584 {
00585 he.NextB();
00586 vr0=&he.v->P();
00587 he.FlipV();
00588 he.NextB();
00589 assert(&he.v->P()==vl);
00590 he.NextB();
00591 vl0=&he.v->P();
00592 nv.P()=((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
00593 }
00594 else
00595 {
00596 he.FlipE();he.FlipV();
00597 vu=&he.v->P();
00598 he.FlipF();he.FlipE();he.FlipV();
00599 vur=&he.v->P();
00600 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
00601 he.FlipE();
00602 he.FlipF();he.FlipE();he.FlipV();
00603 vul=&he.v->P();
00604 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vu);
00605 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vl);
00606 he.FlipE();he.FlipV();
00607 vd=&he.v->P();
00608 he.FlipF();he.FlipE();he.FlipV();
00609 vdl=&he.v->P();
00610 he.FlipV();he.FlipE();he.FlipF(); assert(&he.v->P()==vd);
00611 he.FlipE();
00612 he.FlipF();he.FlipE();he.FlipV();
00613 vdr=&he.v->P();
00614
00615 nv.P()=((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
00616 }
00617 }
00618
00620 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00621 {
00622 Color4<typename MESH_TYPE::ScalarType> cc;
00623 return cc.lerp(c0,c1,0.5f);
00624 }
00625
00626 template<class FL_TYPE>
00627 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00628 {
00629 TexCoord2<FL_TYPE,1> tmp;
00630 assert(t0.n()== t1.n());
00631 tmp.n()=t0.n();
00632 tmp.t()=(t0.t()+t1.t())/2.0;
00633 return tmp;
00634 }
00635 };
00636
00637
00638 #if 0
00639 int rule=0;
00640 if(vr==vul) rule+=1;
00641 if(vl==vur) rule+=2;
00642 if(vl==vdr) rule+=4;
00643 if(vr==vdl) rule+=8;
00644 switch(rule){
00645
00646 case 0 : return ((*vl)+(*vr))/2.0+((*vu)+(*vd))/8.0 - ((*vul)+(*vur)+(*vdl)+(*vdr))/16.0;
00647 case 1 : return (*vl*6 + *vr*10 + *vu + *vd*3 - *vur - *vdl -*vdr*2 )/16.0;
00648 case 2 : return (*vr*6 + *vl*10 + *vu + *vd*3 - *vul - *vdr -*vdl*2 )/16.0;
00649 case 4 : return (*vr*6 + *vl*10 + *vd + *vu*3 - *vdl - *vur -*vul*2 )/16.0;
00650 case 8 : return (*vl*6 + *vr*10 + *vd + *vu*3 - *vdr - *vul -*vur*2 )/16.0;
00651 case 3 : return (*vl*4 + *vr*4 + *vd*2 + - *vdr - *vdl )/8.0;
00652 case 12 : return (*vl*4 + *vr*4 + *vu*2 + - *vur - *vul )/8.0;
00653
00654 case 5 :
00655 case 10 :
00656 default:
00657 return (*vl+ *vr)/2.0;
00658 }
00659
00660
00661
00662 #endif
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 template<class MESH_TYPE>
00679 struct MidPointButterfly2 : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00680 {
00681 typename MESH_TYPE::CoordType operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
00682 {
00683 double Rules[11][10] =
00684 {
00685 {.0},
00686 {.0},
00687 {.0},
00688 { .4166666667, -.08333333333 , -.08333333333 },
00689 { .375 , .0 , -0.125 , .0 },
00690 { .35 , .03090169945 , -.08090169945 , -.08090169945, .03090169945 },
00691 { .5 , .125 , -0.0625 , .0 , -0.0625 , 0.125 },
00692 { .25 , .1088899050 , -.06042933822 , -.04846056675, -.04846056675, -.06042933822, .1088899050 },
00693 { .21875 , .1196383476 , -.03125 , -.05713834763, -.03125 , -.05713834763, -.03125 ,.1196383476 },
00694 { .1944444444, .1225409480 , -.00513312590 , -.05555555556, -.03407448880, -.03407448880, -.05555555556, -.00513312590, .1225409480 },
00695 { .175 , .1213525492 , .01545084973 , -.04635254918, -.04045084973, -.025 , -.04045084973, -.04635254918, .01545084973, .1213525492 }
00696 };
00697
00698 face::Pos<typename MESH_TYPE::FaceType> he(ep.f,ep.z,ep.f->V(ep.z));
00699 typename MESH_TYPE::CoordType *vl,*vr;
00700 vl=&he.v->P();
00701 vr=&he.VFlip()->P();
00702 if(he.IsBorder())
00703 {he.FlipV();
00704 typename MESH_TYPE::CoordType *vl0,*vr0;
00705 he.NextB();
00706 vr0=&he.v->P();
00707 he.FlipV();
00708 he.NextB();
00709 assert(&he.v->P()==vl);
00710 he.NextB();
00711 vl0=&he.v->P();
00712 return ((*vl)+(*vr))*(9.0/16.0)-((*vl0)+(*vr0))/16.0 ;
00713 }
00714
00715 int kl=0,kr=0;
00716 bool bl=false,br=false;
00717 face::Pos<typename MESH_TYPE::FaceType> heStart=he;assert(he.v->P()==*vl);
00718 do {
00719 he.FlipE();he.FlipF();
00720 if(he.IsBorder()) bl=true;
00721 ++kl;
00722 } while(he!=heStart);
00723
00724 he.FlipV();heStart=he;assert(he.v->P()==*vr);
00725 do {
00726 he.FlipE();he.FlipF();
00727 if(he.IsBorder()) br=true;
00728 ++kr;
00729 } while(he!=heStart);
00730 if(br||bl) return MidPointButterfly<MESH_TYPE>()( ep );
00731 if(kr==6 && kl==6) return MidPointButterfly<MESH_TYPE>()( ep );
00732
00733 typename MESH_TYPE::CoordType newposl=*vl*.75, newposr=*vr*.75;
00734 he.FlipV();heStart=he; assert(he.v->P()==*vl);
00735 int i=0;
00736 if(kl!=6)
00737 do {
00738 newposl+= he.VFlip()->P() * Rules[kl][i];
00739 he.FlipE();he.FlipF();
00740 ++i;
00741 } while(he!=heStart);
00742 i=0;he.FlipV();heStart=he;assert(he.v->P()==*vr);
00743 if(kr!=6)
00744 do {
00745 newposr+=he.VFlip()->P()* Rules[kr][i];
00746 he.FlipE();he.FlipF();
00747 ++i;
00748 } while(he!=heStart);
00749 if(kr==6) return newposl;
00750 if(kl==6) return newposr;
00751 return newposl+newposr;
00752 }
00753 };
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 template<class MESH_TYPE>
00770 class QualityMidPointFunctor : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00771 {
00772 public:
00773 typedef Point3<typename MESH_TYPE::ScalarType> Point3x;
00774 typedef typename MESH_TYPE::ScalarType ScalarType;
00775
00776 ScalarType thr;
00777
00778 QualityMidPointFunctor(ScalarType _thr):thr(_thr){}
00779
00780
00781 void operator()(typename MESH_TYPE::VertexType &nv, const face::Pos<typename MESH_TYPE::FaceType> &ep){
00782 Point3x p0=ep.f->V0(ep.z)->P();
00783 Point3x p1=ep.f->V1(ep.z)->P();
00784 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
00785 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
00786 double pp= q0/(q0-q1);
00787 nv.P()=p1*pp + p0*(1.0-pp);
00788 nv.Q()=thr;
00789 }
00790
00791 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00792 {
00793 Color4<typename MESH_TYPE::ScalarType> cc;
00794 return cc.lerp(c0,c1,0.5f);
00795 }
00796
00797 template<class FL_TYPE>
00798 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00799 {
00800 TexCoord2<FL_TYPE,1> tmp;
00801 assert(t0.n()== t1.n());
00802 tmp.n()=t0.n();
00803 tmp.t()=(t0.t()+t1.t())/2.0;
00804 return tmp;
00805 }
00806 };
00807
00808
00809 template <class MESH_TYPE>
00810 class QualityEdgePredicate
00811 {
00812 public:
00813 typedef Point3<typename MESH_TYPE::ScalarType> Point3x;
00814 typedef typename MESH_TYPE::ScalarType ScalarType;
00815 ScalarType thr;
00816 ScalarType tolerance;
00817 QualityEdgePredicate(const ScalarType &thr,ScalarType _tolerance=0.02):thr(thr) {tolerance=_tolerance;}
00818 bool operator()(face::Pos<typename MESH_TYPE::FaceType> ep)
00819 {
00820 ScalarType q0=ep.f->V0(ep.z)->Q()-thr;
00821 ScalarType q1=ep.f->V1(ep.z)->Q()-thr;
00822 if(q0>q1) std::swap(q0,q1);
00823 if ( q0*q1 >= 0) return false;
00824
00825 double pp= q0/(q0-q1);
00826 if ((fabs(pp)< tolerance)||(fabs(pp)> (1-tolerance))) return false;
00827 return true;
00828 }
00829 };
00830
00831
00832 template<class MESH_TYPE>
00833 struct MidPointSphere : public std::unary_function<face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType>
00834 {
00835 Sphere3<typename MESH_TYPE::ScalarType> sph;
00836 typedef Point3<typename MESH_TYPE::ScalarType> Point3x;
00837
00838 void operator()(typename MESH_TYPE::VertexType &nv, face::Pos<typename MESH_TYPE::FaceType> ep){
00839 Point3x &p0=ep.f->V0(ep.z)->P();
00840 Point3x &p1=ep.f->V1(ep.z)->P();
00841 nv.P()= sph.c+((p0+p1)/2.0 - sph.c ).Normalize();
00842 }
00843
00844 Color4<typename MESH_TYPE::ScalarType> WedgeInterp(Color4<typename MESH_TYPE::ScalarType> &c0, Color4<typename MESH_TYPE::ScalarType> &c1)
00845 {
00846 Color4<typename MESH_TYPE::ScalarType> cc;
00847 return cc.lerp(c0,c1,0.5f);
00848 }
00849
00850 template<class FL_TYPE>
00851 TexCoord2<FL_TYPE,1> WedgeInterp(TexCoord2<FL_TYPE,1> &t0, TexCoord2<FL_TYPE,1> &t1)
00852 {
00853 TexCoord2<FL_TYPE,1> tmp;
00854 assert(t0.n()== t1.n());
00855 tmp.n()=t0.n();
00856 tmp.t()=(t0.t()+t1.t())/2.0;
00857 return tmp;
00858 }
00859 };
00860
00861
00862 template <class FLT>
00863 class EdgeSplSphere
00864 {
00865 public:
00866 Sphere3<FLT> sph;
00867 bool operator()(const Point3<FLT> &p0, const Point3<FLT> &p1) const
00868 {
00869 if(Distance(sph,p0)>0) {
00870 if(Distance(sph,p1)>0) return false;
00871 else return true;
00872 }
00873 else if(Distance(sph,p1)<=0) return false;
00874 return true;
00875 }
00876 };
00877
00878 template<class TRIMESH_TYPE>
00879 struct CenterPointBarycenter : public std::unary_function<typename TRIMESH_TYPE::FacePointer, typename TRIMESH_TYPE::CoordType>
00880 {
00881 typename TRIMESH_TYPE::CoordType operator()(typename TRIMESH_TYPE::FacePointer f){
00882 return vcg::Barycenter<typename TRIMESH_TYPE::FaceType>(*f);
00883 }
00884 };
00885
00889
00890 template<class TRIMESH_TYPE, class CenterPoint=CenterPointBarycenter <TRIMESH_TYPE> >
00891 class TriSplit
00892 {
00893 public:
00894 typedef typename TRIMESH_TYPE::FaceType FaceType;
00895 typedef typename TRIMESH_TYPE::VertexType VertexType;
00896
00897 static void Apply(FaceType *f,
00898 FaceType * f1,FaceType * f2,
00899 VertexType * vB, CenterPoint Center)
00900 {
00901 vB->P() = Center(f);
00902
00903
00904 VertexType *V0,*V1,*V2;
00905 V0 = f->V(0);
00906 V1 = f->V(1);
00907 V2 = f->V(2);
00908
00909
00910 (*f).V(2) = &(*vB);
00911
00912 (*f1).V(0) = &(*vB);
00913 (*f1).V(1) = V1;
00914 (*f1).V(2) = V2;
00915
00916 (*f2).V(0) = V0;
00917 (*f2).V(1) = &(*vB);
00918 (*f2).V(2) = V2;
00919
00920 if(f->HasFFAdjacency())
00921 {
00922
00923 f->FFp(1)->FFp(f->FFi(1)) = f1;
00924 f->FFp(2)->FFp(f->FFi(2)) = f2;
00925
00926
00927 FaceType * FF0,*FF1,*FF2;
00928 FF0 = f->FFp(0);
00929 FF1 = f->FFp(1);
00930 FF2 = f->FFp(2);
00931
00932
00933 char FFi0,FFi1,FFi2;
00934 FFi0 = f->FFi(0);
00935 FFi1 = f->FFi(1);
00936 FFi2 = f->FFi(2);
00937
00938
00939 (*f).FFp(1) = &(*f1);
00940 (*f).FFi(1) = 0;
00941 (*f).FFp(2) = &(*f2);
00942 (*f).FFi(2) = 0;
00943
00944
00945 (*f1).FFp(0) = f;
00946 (*f1).FFi(0) = 1;
00947
00948 (*f1).FFp(1) = FF1;
00949 (*f1).FFi(1) = FFi1;
00950
00951 (*f1).FFp(2) = &(*f2);
00952 (*f1).FFi(2) = 1;
00953
00954
00955 (*f2).FFp(0) = f;
00956 (*f2).FFi(0) = 2;
00957
00958 (*f2).FFp(1) = &(*f1);
00959 (*f2).FFi(1) = 2;
00960
00961 (*f2).FFp(2) = FF2;
00962 (*f2).FFi(2) = FFi2;
00963 }
00964 }
00965 };
00966
00967 template <class MeshType>
00968 void TrivialMidPointRefine(MeshType & m)
00969 {
00970 typedef typename MeshType::VertexIterator VertexIterator;
00971 typedef typename MeshType::FaceIterator FaceIterator;
00972 typedef typename MeshType::VertexPointer VertexPointer;
00973 typedef typename MeshType::FacePointer FacePointer;
00974
00975 Allocator<MeshType>::CompactEveryVector(m);
00976 int startFn = m.fn;
00977 FaceIterator lastf = tri::Allocator<MeshType>::AddFaces(m,m.fn*3);
00978 VertexIterator lastv = tri::Allocator<MeshType>::AddVertices(m,m.fn*3);
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 for(int i=0;i<startFn;++i)
00994 {
00995 FacePointer f0= &m.face[i];
00996 FacePointer f1= &*lastf; ++lastf;
00997 FacePointer f2= &*lastf; ++lastf;
00998 FacePointer f3= &*lastf; ++lastf;
00999 VertexPointer v0 =m.face[i].V(0);
01000 VertexPointer v1 =m.face[i].V(1);
01001 VertexPointer v2 =m.face[i].V(2);
01002 VertexPointer mp01 = &*lastv; ++lastv;
01003 VertexPointer mp12 = &*lastv; ++lastv;
01004 VertexPointer mp02 = &*lastv; ++lastv;
01005
01006 f0->V(0) = v0; f0->V(1) = mp01; f0->V(2) = mp02;
01007 f1->V(0) = v1; f1->V(1) = mp12; f1->V(2) = mp01;
01008 f2->V(0) = v2; f2->V(1) = mp02; f2->V(2) = mp12;
01009 f3->V(0) = mp12; f3->V(1) = mp02; f3->V(2) = mp01;
01010 mp01->P() = (v0>v1) ? (v0->P()+v1->P())/2.0 : (v1->P()+v0->P())/2.0;
01011 mp12->P() = (v1>v2) ? (v1->P()+v2->P())/2.0 : (v2->P()+v1->P())/2.0;
01012 mp02->P() = (v0>v2) ? (v0->P()+v2->P())/2.0 : (v2->P()+v0->P())/2.0;
01013 }
01014
01015 int vd = tri::Clean<MeshType>::RemoveDuplicateVertex(m);
01016 printf("Vertex unification %i\n",vd);
01017 int vu = tri::Clean<MeshType>::RemoveUnreferencedVertex(m);
01018 printf("Vertex unref %i\n",vu);
01019 Allocator<MeshType>::CompactEveryVector(m);
01020 }
01021
01022 }
01023 }
01024
01025 #endif