00001 #include <vcg/complex/trimesh/bitquad_support.h>
00002 #include <vcg/complex/trimesh/allocate.h>
00003
00052 #ifndef VCG_BITQUAD_CRE
00053 #define VCG_BITQUAD_CRE
00054
00055 namespace vcg{namespace tri{
00056
00057 template <class _MeshType,
00058 class Interpolator = GeometricInterpolator<typename _MeshType::VertexType> >
00059 class BitQuadCreation{
00060
00061 public:
00062
00063 typedef _MeshType MeshType;
00064 typedef typename MeshType::ScalarType ScalarType;
00065 typedef typename MeshType::CoordType CoordType;
00066 typedef typename MeshType::FaceType FaceType;
00067 typedef typename MeshType::FaceType* FaceTypeP;
00068 typedef typename MeshType::VertexType VertexType;
00069 typedef typename MeshType::FaceIterator FaceIterator;
00070 typedef typename MeshType::VertexIterator VertexIterator;
00071
00072 typedef BitQuad<MeshType> BQ;
00073
00074
00075
00076
00077 template <bool override>
00078 static void selectBestDiag(FaceType *fi){
00079
00080 if (!override) {
00081 if (fi->IsAnyF()) return;
00082 }
00083
00084
00085 int whichEdge = -1;
00086 ScalarType bestScore = fi->Q();
00087
00088 whichEdge=-1;
00089
00090 for (int k=0; k<3; k++){
00091
00092
00093
00094 if (!override) {
00095 if (fi->FFp(k)->IsAnyF()) continue;
00096 }
00097 if (fi->FFp(k)==fi) continue;
00098
00099 ScalarType score = BQ::quadQuality( &*fi, k );
00100 if (override) {
00101
00102 if (score < fi->FFp(k)->Q()) continue;
00103 }
00104 if (score>bestScore) {
00105 bestScore = score;
00106 whichEdge = k;
00107 }
00108 }
00109
00110
00111 if (whichEdge>=0) {
00112
00113
00114
00115
00116
00117
00118 if (override) {
00119
00120 for (int k=0; k<3; k++)
00121 if (fi->FFp(whichEdge)->IsF(k)) {
00122 fi->FFp(whichEdge)->ClearF(k);
00123 fi->FFp(whichEdge)->FFp(k)->ClearF( fi->FFp(whichEdge)->FFi(k) );
00124 fi->FFp(whichEdge)->FFp(k)->Q()=0.0;
00125 }
00126
00127
00128 for (int k=0; k<3; k++)
00129 if (fi->IsF(k)) {
00130 fi->ClearF(k);
00131 fi->FFp(k)->ClearF( fi->FFi(k) );
00132 fi->FFp(k)->Q()= 0.0;
00133 }
00134 }
00135
00136 fi->SetF(whichEdge);
00137 fi->FFp(whichEdge)->SetF( fi->FFi(whichEdge) );
00138 fi->Q() = fi->FFp(whichEdge)->Q() = bestScore;
00139
00140 }
00141
00142
00143 }
00144
00145
00146
00147
00148
00149 template <bool override>
00150 static void MakeDominantPass(MeshType &m){
00151
00152 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) if (!fi->IsD()) {
00153 selectBestDiag<override>(&(*fi));
00154 }
00155
00156 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 static std::pair<typename MeshType::FaceType *, typename MeshType::VertexType *> FaceSplitBorderEdge(MeshType &m, typename MeshType::FaceType &f, int edge, typename MeshType::FaceType *newFace, typename MeshType::VertexType *newVert )
00174 {
00175 assert(tri::HasFFAdjacency(m));
00176 assert(face::IsBorder(f,edge));
00177
00178 if(newFace==0) newFace=&*tri::Allocator<MeshType>::AddFaces(m,1);
00179 if(newVert==0) {
00180 newVert=&*tri::Allocator<MeshType>::AddVertices(m,1);
00181 newVert->P()=(f.P0(edge)+f.P1(edge))/2.0;
00182 }
00183 newFace->V0(edge)=newVert;
00184 newFace->V1(edge)=f.V1(edge);
00185 newFace->V2(edge)=f.V2(edge);
00186
00187 f.V1(edge)=newVert;
00188
00189
00190
00191
00192
00193
00194 newFace->FFp((edge+2)%3) = &f;
00195 newFace->FFi((edge+2)%3) = (edge+1)%3;
00196
00197 newFace->FFp((edge+0)%3) = newFace;
00198 newFace->FFi((edge+0)%3) = (edge+0)%3;
00199
00200 newFace->FFp((edge+2)%3) = f.FFp((edge+1)%3);
00201 newFace->FFi((edge+2)%3) = f.FFi((edge+1)%3);
00202
00203 f.FFp((edge+1)%3) = newFace;
00204 f.FFi((edge+1)%3) = (edge+2)%3;
00205
00206
00207 assert(face::IsBorder(f,edge));
00208 assert(face::IsBorder(*newFace,edge));
00209
00210 return std::make_pair(newFace,newVert);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 static bool MakeTriEvenBySplit(MeshType& m){
00223 if (m.fn%2==0) return false;
00224
00225 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++)
00226 {
00227 if(!(*fi).IsD())
00228 {
00229 for (int k=0; k<3; k++) {
00230 if (face::IsBorder(*fi,k)){
00231
00232 int index=tri::Index(m,*fi);
00233 VertexIterator vnew=tri::Allocator<MeshType>::AddVertices(m,1);
00234 (*vnew).P()=((*fi).P0(k)+(*fi).P1(k))/2.0;
00235
00236 FaceIterator fnew=tri::Allocator<MeshType>::AddFaces(m,1);
00237
00238 FaceSplitBorderEdge(m,m.face[index],k,&*fnew,&*vnew);
00239 return true;
00240 }
00241 }
00242 }
00243
00244 }
00245 return true;
00246 }
00247
00248
00249 static bool MakeTriEvenByDelete(MeshType& m)
00250 {
00251 if (m.fn%2==0) return false;
00252
00253 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) {
00254 for (int k=0; k<3; k++) {
00255 if (face::IsBorder(*fi,k) ) {
00256 FFDetachManifold(*fi,(k+1)%3);
00257 FFDetachManifold(*fi,(k+2)%3);
00258 Allocator<MeshType>::DeleteFace(m,*fi);
00259 return true;
00260 }
00261 }
00262 }
00263 assert(0);
00264 return true;
00265 }
00266
00267
00271 static void MakeBitTriOnly(MeshType &m){
00272 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) {
00273 fi->ClearAllF();
00274 }
00275 }
00276
00283 static bool MakeBitTriQuadConventional(MeshType &m){
00284 assert(0);
00285 }
00286
00287
00288
00289 static bool IsBitTriQuadConventional(MeshType &m){
00290 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) if (!fi->IsD()) {
00291 if (fi->IsAnyF())
00292 if ( fi->Flags() & ( FaceType::FAUX012 ) != FaceType::FAUX2 ) {
00293 return false;
00294 }
00295 }
00296 return true;
00297 }
00298 static void CopyTopology(FaceType *fnew, FaceType * fold)
00299 {
00300 fnew->FFp(0)=fold->FFp(0); fnew->FFi(0)=fold->FFi(0);
00301 fnew->FFp(1)=fold->FFp(1); fnew->FFi(1)=fold->FFi(1);
00302 fnew->FFp(2)=fold->FFp(2); fnew->FFi(2)=fold->FFi(2);
00303 fnew->V(0) = fold->V(0);
00304 fnew->V(1) = fold->V(1);
00305 fnew->V(2) = fold->V(2);
00306 }
00312 static void MakePureByRefine(MeshType &m){
00313
00314
00315
00316
00317 int ev = 0;
00318 int ef = 0;
00319
00320
00321 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) if (!fi->IsD()) {
00322 int k=0;
00323 if (face::IsBorder(*fi,0)) k++;
00324 if (face::IsBorder(*fi,1)) k++;
00325 if (face::IsBorder(*fi,2)) k++;
00326 if (!fi->IsAnyF()) {
00327
00328 if (k==0)
00329 { ev+=2; ef+=2; }
00330 if (k==1)
00331 { }
00332 if (k==2)
00333 { }
00334 if (k==3)
00335 { }
00336 }
00337 else {
00338
00339
00340 ev+=1; ef+=1;
00341 assert(k!=3);
00342 }
00343 }
00344 assert(ev%2==0);
00345 ev/=2;
00346
00347
00348 FaceIterator nfi = tri::Allocator<MeshType>::AddFaces(m,ef);
00349 VertexIterator nvi = tri::Allocator<MeshType>::AddVertices(m,ev);
00350
00351 tri::UpdateFlags<MeshType>::FaceClearV(m);
00352
00353
00354 int nsplit=0;
00355 for (FaceIterator fi = m.face.begin(), fend = nfi; fi!=fend; fi++) if (!fi->IsD() && !fi->IsV() ) {
00356
00357 fi->SetV();
00358
00359 if (!fi->IsAnyF()) {
00360
00361
00362 int k=0;
00363 if (face::IsBorder(*fi,0)) k++;
00364 if (face::IsBorder(*fi,1)) k++;
00365 if (face::IsBorder(*fi,2)) k++;
00366
00367 if (k==0)
00368 {
00369 assert(nvi!=m.vert.end());
00370 VertexType *nv = &*nvi; nvi++;
00371
00372 nv->ImportData(*(fi->V0( 0 )));
00373
00374 nv->P() = ( fi->V(0)->P() + fi->V(1)->P() + fi->V(2)->P() ) /3.0;
00375 FaceType *fa = &*fi;
00376 FaceType *fb = &*nfi; nfi++;
00377 FaceType *fc = &*nfi; nfi++;
00378
00379 fb->ImportData(*fa); CopyTopology(fb,fa);
00380 fc->ImportData(*fa); CopyTopology(fc,fa);
00381
00382 fa->V(0) = nv;
00383 fb->V(1) = nv;
00384 fc->V(2) = nv;
00385
00386 fb->FFp(2)=fa->FFp(2); fb->FFi(2)=fa->FFi(2);
00387 fc->FFp(0)=fa->FFp(0); fc->FFi(0)=fa->FFi(0);
00388
00389 assert( fa->FFp(1)->FFp(fa->FFi(1)) == fa );
00390 fb->FFp(2)->FFp(fb->FFi(2)) = fb;
00391 fc->FFp(0)->FFp(fc->FFi(0)) = fc;
00392
00393 fa->FFp(0) = fc; fa->FFp(2) = fb; fa->FFi(0) = fa->FFi(2) = 1;
00394 fb->FFp(1) = fa; fb->FFp(0) = fc; fb->FFi(0) = fb->FFi(1) = 2;
00395 fc->FFp(1) = fa; fc->FFp(2) = fb; fc->FFi(1) = fc->FFi(2) = 0;
00396
00397 if (fb->FFp(2)==fa) fb->FFp(2)=fb;
00398 if (fc->FFp(0)==fa) fc->FFp(0)=fc;
00399
00400 fa->ClearAllF();
00401 fb->ClearAllF();
00402 fc->ClearAllF();
00403 fa->SetF(1);
00404 fb->SetF(2);
00405 fc->SetF(0);
00406
00407 fa->SetV();fb->SetV();fc->SetV();
00408 }
00409 if (k==1) {
00410 fi->SetF(0);
00411 fi->SetF(1);
00412 fi->SetF(2);
00413 nsplit++;
00414 }
00415 if (k==2)
00416 {
00417 fi->ClearAllF();
00418 for (int w=0; w<3; w++) if (fi->FFp(w) != &*fi) fi->SetF(w);
00419 }
00420 if (k==3)
00421 {
00422 fi->ClearAllF();
00423 fi->SetF(2);
00424 nsplit++;
00425 }
00426 }
00427 else {
00428
00429 FaceType *fa = &*fi;
00430 int ea2 = BQ::FauxIndex(fa);
00431 FaceType *fb = fa->FFp(ea2);
00432 int eb2 = fa->FFi(ea2);
00433 assert(fb->FFp(eb2)==fa) ;
00434 assert(fa->IsF(ea2));
00435
00436
00437 int ea0 = (ea2+1) %3;
00438 int ea1 = (ea2+2) %3;
00439 int eb0 = (eb2+1) %3;
00440 int eb1 = (eb2+2) %3;
00441
00442
00443 assert(nvi!=m.vert.end());
00444 VertexType *nv = &*nvi; nvi++;
00445
00446 nv->ImportData(*(fa->V0( ea2 ) ));
00447
00448 Interpolator::Apply(*(fa->V(ea2)),*(fa->V(ea0)),0.5,*nv);
00449
00450 assert(nfi!=m.face.end());
00451 FaceType *fc = &*nfi; nfi++;
00452 assert(nfi!=m.face.end());
00453 FaceType *fd = &*nfi; nfi++;
00454
00455 fc->ImportData(*fa ); CopyTopology(fc,fa);
00456 fd->ImportData(*fb ); CopyTopology(fd,fb);
00457
00458 fa->V(ea2) = fc->V(ea0) =
00459 fb->V(eb2) = fd->V(eb0) = nv ;
00460
00461 fa->FFp(ea1)->FFp( fa->FFi(ea1) ) = fc;
00462 fb->FFp(eb1)->FFp( fb->FFi(eb1) ) = fd;
00463
00464 fa->FFp(ea1) = fc ; fa->FFp(ea2) = fd;
00465 fa->FFi(ea1) = ea0; fa->FFi(ea2) = eb2;
00466 fb->FFp(eb1) = fd ; fb->FFp(eb2) = fc;
00467 fb->FFi(eb1) = eb0; fb->FFi(eb2) = ea2;
00468 fc->FFp(ea0) = fa ; fc->FFp(ea2) = fb;
00469 fc->FFi(ea0) = ea1; fc->FFi(ea2) = eb2;
00470 fd->FFp(eb0) = fb ; fd->FFp(eb2) = fa;
00471 fd->FFi(eb0) = eb1; fd->FFi(eb2) = ea2;
00472
00473
00474 bool ba = fa->FFp(ea0)==fa;
00475 bool bc = fc->FFp(ea1)==fa;
00476 bool bb = fb->FFp(eb0)==fb;
00477 bool bd = fd->FFp(eb1)==fb;
00478
00479 if (bc) fc->FFp(ea1)=fc;
00480 if (bd) fd->FFp(eb1)=fd;
00481
00482 fa->SetV();
00483 fb->SetV();
00484 fc->SetV();
00485 fd->SetV();
00486
00487 fa->ClearAllF();
00488 fb->ClearAllF();
00489 fc->ClearAllF();
00490 fd->ClearAllF();
00491
00492 fa->SetF( ea0 );
00493 fb->SetF( eb0 );
00494 fc->SetF( ea1 );
00495 fd->SetF( eb1 );
00496
00497
00498 if (ba&&bc) {
00499 fa->ClearAllF(); fa->SetF(ea1);
00500 fc->ClearAllF(); fc->SetF(ea0);
00501 ba = bc = false;
00502 }
00503 if (bc&&bb) {
00504 fc->ClearAllF(); fc->SetF(ea2);
00505 fb->ClearAllF(); fb->SetF(eb2);
00506 bc = bb = false;
00507 }
00508 if (bb&&bd) {
00509 fb->ClearAllF(); fb->SetF(eb1);
00510 fd->ClearAllF(); fd->SetF(eb0);
00511 bb = bd = false;
00512 }
00513 if (bd&&ba) {
00514 fd->ClearAllF(); fd->SetF(eb2);
00515 fa->ClearAllF(); fa->SetF(ea2);
00516 bd = ba = false;
00517 }
00518
00519 if (ba) nsplit++;
00520 if (bb) nsplit++;
00521 if (bc) nsplit++;
00522 if (bd) nsplit++;
00523 }
00524 }
00525 assert(nfi==m.face.end());
00526 assert(nvi==m.vert.end());
00527
00528
00529
00530
00531
00532 if (nsplit>0) {
00533 FaceIterator nfi = tri::Allocator<MeshType>::AddFaces(m,nsplit);
00534 VertexIterator nvi = tri::Allocator<MeshType>::AddVertices(m,nsplit);
00535 for (FaceIterator fi = m.face.begin(), fend = nfi; fi!=fend; fi++) if (!fi->IsD()) {
00536 FaceType* fa = &*fi;
00537 int ea2 = -1;
00538 if (fa->FFp(0)==fa && fa->IsF(0) ) ea2=0;
00539 if (fa->FFp(1)==fa && fa->IsF(1) ) ea2=1;
00540 if (fa->FFp(2)==fa && fa->IsF(2) ) ea2=2;
00541
00542 if (ea2 != -1) {
00543
00544 int ea0 = (ea2+1) %3;
00545 int ea1 = (ea2+2) %3;
00546
00547
00548 VertexType *nv = &*nvi; nvi++;
00549
00550 nv->ImportData(*(fa->V0( ea2 ) ));
00551 nv->P() = ( fa->V(ea2)->P() + fa->V(ea0)->P() ) /2.0;
00552 Interpolator::Apply(*(fa->V(ea2)),*(fa->V(ea0)),0.5,*nv);
00553
00554 FaceType *fc = &*nfi; nfi++;
00555
00556 fc->ImportData(*fa);CopyTopology(fc,fa);
00557
00558 fa->V(ea2) = fc->V(ea0) = nv ;
00559
00560 fc->FFp(ea2) = fc;
00561
00562 fa->FFp(ea1)->FFp( fa->FFi(ea1) ) = fc;
00563
00564 fa->FFp(ea1) = fc ;
00565 fa->FFi(ea1) = ea0;
00566 fc->FFp(ea0) = fa ; fc->FFp(ea2) = fc;
00567 fc->FFi(ea0) = ea1;
00568
00569 if (fc->FFp(ea1)==fa) fc->FFp(ea1)=fc;
00570
00571 assert(fa->IsF(ea0) == fa->IsF(ea1) );
00572 bool b = fa->IsF(ea1);
00573
00574 fa->ClearAllF();
00575 fc->ClearAllF();
00576
00577 if (b) {
00578 fa->SetF( ea0 );
00579 fc->SetF( ea1 );
00580 } else {
00581 fa->SetF( ea1 );
00582 fc->SetF( ea0 );
00583 }
00584 }
00585 }
00586 }
00587
00588
00589 }
00590
00591
00592
00593
00594 static void MakePureByCatmullClark(MeshType &m){
00595 MakePureByRefine(m);
00596 MakePureByRefine(m);
00597
00598 }
00599
00600
00601
00602
00603 static FaceType * MarkEdgeDistance(MeshType &m, FaceType *f, int maxDist){
00604 assert(tri::HasPerFaceQuality(m));
00605
00606 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) if (!f->IsD()) {
00607 fi->Q()=maxDist;
00608 }
00609
00610 FaceType * firstTriangleFound = NULL;
00611
00612 f->Q() = 0;
00613 std::vector<FaceType*> stack;
00614 int stackPos=0;
00615 stack.push_back(f);
00616
00617 while ( stackPos<int(stack.size())) {
00618 FaceType *f = stack[stackPos++];
00619 for (int k=0; k<3; k++) {
00620 FaceType *fk = f->FFp(k);
00621 int fq = int(f->Q()) + ( ! f->IsF(k) );
00622 if (fk->Q()> fq && fq <= maxDist) {
00623 if (!fk->IsAnyF()) { firstTriangleFound = fk; maxDist = fq;}
00624 fk->Q() = fq;
00625 stack.push_back(fk);
00626 }
00627 }
00628 }
00629 return firstTriangleFound;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 static int MakePureByFlipStepByStep(MeshType &m, int maxdist=10000, int restart=false){
00644
00645 static FaceType *ta, *tb;
00646
00647 static int step = 0;
00648
00649 if (restart) { step=0; return false; }
00650 if (step==0) {
00651
00652
00653 ta = NULL;
00654 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) if (!fi->IsD()) {
00655 if (!fi->IsAnyF()) { ta=&*fi; break; }
00656 }
00657 if (!ta) return 0;
00658
00659
00660 tb = MarkEdgeDistance(m,ta,maxdist);
00661 if (!tb) return 1;
00662
00663 step=1;
00664
00665 } else {
00666 int marriageEdge=-1;
00667 bool done = false;
00668 while (!done) {
00669
00670 int bestScore = int(tb->Q());
00671 int edge = -1;
00672 bool mustDoFlip;
00673
00674
00675 for (int k=0; k<3; k++) {
00676 if (tb->FFp(k) == tb) continue;
00677
00678 FaceType* tbk = tb->FFp(k);
00679
00680 if (!tbk->IsAnyF()) {done=true; marriageEdge=k; break; }
00681
00682 int back = tb->FFi(k);
00683 int faux = BQ::FauxIndex(tbk);
00684 int other = 3-back-faux;
00685
00686 int scoreA = int(tbk->FFp(other)->Q());
00687
00688 FaceType* tbh = tbk->FFp(faux);
00689 int fauxh = BQ::FauxIndex(tbh);
00690
00691 int scoreB = int(tbh->FFp( (fauxh+1)%3 )->Q());
00692 int scoreC = int(tbh->FFp( (fauxh+2)%3 )->Q());
00693
00694 int scoreABC = std::min( scoreC, std::min( scoreA, scoreB ) );
00695 if (scoreABC<bestScore) {
00696 bestScore = scoreABC;
00697 edge = k;
00698 mustDoFlip = !(scoreB == scoreABC || scoreC == scoreABC);
00699 }
00700 }
00701
00702 if (done) break;
00703
00704
00705 if (mustDoFlip) {
00706 BQ::FlipDiag( *(tb->FFp(edge)) );
00707 }
00708
00709 FaceType* next = tb->FFp(edge)->FFp( BQ::FauxIndex(tb->FFp(edge)) );
00710
00711
00712 next->ClearAllF();
00713 tb->FFp(edge)->ClearAllF();
00714
00715
00716 tb->SetF(edge);
00717 tb->FFp(edge)->SetF( tb->FFi(edge) );
00718 tb->FFp(edge)->Q() = tb->Q();
00719
00720 tb = next;
00721 break;
00722 }
00723
00724 if (marriageEdge!=-1) {
00725
00726 assert(!(tb->IsAnyF()));
00727 assert(!(tb->FFp(marriageEdge)->IsAnyF()));
00728 tb->SetF(marriageEdge);
00729 tb->FFp(marriageEdge)->SetF(tb->FFi(marriageEdge));
00730
00731 step=0;
00732 }
00733 }
00734 return -1;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743 static bool MakePureByFlip(MeshType &m, int maxdist=10000)
00744 {
00745 MakePureByFlipStepByStep(m, maxdist, true);
00746 int res=-1;
00747 while (res==-1) res = MakePureByFlipStepByStep(m, maxdist);
00748 return res==0;
00749 }
00750
00758 static void MakeDominant(MeshType &m, int level){
00759
00760 assert(MeshType::HasPerFaceQuality());
00761 assert(MeshType::HasPerFaceFlags());
00762
00763 for (FaceIterator fi = m.face.begin(); fi!=m.face.end(); fi++) {
00764 fi->ClearAllF();
00765 fi->Q() = 0;
00766 }
00767
00768
00769 MakeDominantPass<false> (m);
00770 if (level>0) MakeDominantPass<true> (m);
00771 if (level>1) MakeDominantPass<true> (m);
00772 if (level>0) MakeDominantPass<false> (m);
00773 }
00774
00775 };
00776 }}
00777 #endif