proj home

Files   Classes   Functions   Hierarchy  

d3tess.cpp

Go to the documentation of this file.
00001 
00002 #include <iomanip>
00003 #include <vector>
00004 #include <sstream>
00005 using namespace std;
00006 
00007 #include <d3fan.h>
00008 #include <d3fan2.h>
00009 #include <d3tess.h>
00010 #include <message.h>
00011 #include <print.h>
00012 #include <simplexD2linked.h>
00013 #include <simplexface.h>
00014 #include <trianglespace.h>
00015 
00016 
00017 
00018 void d3tess::splitmidpoint1D(uintc s, uintc p1)
00019 {
00020   assert(s<vi.size());
00021   assert(p1<pt.size());
00022 
00023   simplexD2linked & S(vi[s]);
00024 
00025   assert(S.piInverseHas(p1)==true);
00026 
00027   uintc j = S.piInverse(p1);
00028 
00029   uintc a = S.pi[(j+1)%3];
00030   uintc b = S.pi[(j+2)%3];
00031 
00032   uintc n = pt.size();
00033   pt.push_back( (pt[a]+pt[b])*0.5 );
00034 
00035   split1D(s,p1,n);
00036 }
00037 
00038 void d3tess::removenullsimplexes()
00039 {    
00040   // Remove any null simplexes at the end of the 
00041   //   tessellation so the last simplex is non null 
00042   //   or there is no tessellation.
00043   if (vi[vi.size()-1].isnull())
00044   {
00045     for ( ; vi[vi.size()-1].isnull() && (vi.size()>1) ; )
00046       vi.pop_back();
00047   }
00048 
00049   // Swap null simplexes with non null simplexes
00050   //   and delete them.
00051   for (uint i=1; i<vi.size(); ++i)
00052   {
00053     if (vi[i].isnull()==false)
00054       continue;
00055 
00056     simplexswap(i,vi.size()-1);
00057     for ( ; vi[vi.size()-1].isnull() && (vi.size()>1) ; )
00058       vi.pop_back();
00059   }
00060 
00061   debugcheck();
00062 }
00063 
00064 void d3tess::simplexswap(uintc s0, uintc s1)
00065 {
00066   assert(s0<vi.size());
00067   assert(s1<vi.size());
00068 
00069   if (s0==s1)
00070     return;
00071 
00072   uint a[3];
00073   uint b[3];
00074 
00075   // Copy the neighbor links of both simplexes.
00076   uint i;
00077 
00078   simplexD2linked & A(vi[s0]);
00079   for (i=0; i<3; ++i)
00080     a[i] = A.ni[i];
00081 
00082   simplexD2linked & B(vi[s1]);
00083   for (i=0; i<3; ++i)
00084     b[i] = B.ni[i];
00085 
00086   // Change the links in the actual mesh.
00087   for (i=0; i<3; ++i)
00088   {
00089     if (a[i]==0)
00090       continue;
00091 
00092     simplexD2linked & x(vi[a[i]]);
00093     if (x.niInverseHas(s1)==false)
00094       x.changelink(s0,s1);
00095     else
00096     {
00097       // The case where the neighbor has both simplexes
00098       //   on its boundary.
00099       uint c = x.niInverse(s1);
00100       x.ni[ x.niInverse(s0) ] = s1;  
00101       x.ni[ c ] = s0;
00102     }
00103   }
00104 
00105   for (i=0; i<3; ++i)
00106   {
00107     if (b[i]==0)
00108       continue;
00109     simplexD2linked & x(vi[b[i]]);
00110     if (x.niInverseHas(s0)==false)
00111       x.changelink(s1,s0);
00112   }
00113 
00114   // Swap the simplexes s0 and s1 in memory
00115   uint c;
00116   for (i=0; i<3; ++i)
00117   {
00118     c = A.pi[i];
00119     A.pi[i] = B.pi[i];
00120     B.pi[i] = c;
00121 
00122     c = A.ni[i];
00123     A.ni[i] = B.ni[i];
00124     B.ni[i] = c;
00125   }
00126 }
00127 
00128   
00129 
00130 void d3tess::splitwithline
00131 ( 
00132   uintc s, 
00133   uintc p0, 
00134   uintc w0, 
00135   uintc p1, 
00136   uintc w1 
00137 )
00138 {
00139   uintc n0 = vi.size();
00140   assert(s<n0);
00141 
00142   // Neighboring triangle opposite p0
00143   uintc neib = vi[s].nifrom(p0);
00144 
00145   // If the first splitting point has no neighbor on the given 
00146   //   boundary then handle this case. 
00147   if (neib==0)
00148   {
00149     split1D(s,p0,w0);
00150     if ( vi[s].piInverseHas(p1) )
00151       split1D(n0,w0,w1);
00152     else
00153       split1D(s,w0,w1);
00154 
00155     return;
00156   }
00157 
00158   // The first split will create 4 new triangles and delete two.
00159 
00160   split1D(s,p0,w0);
00161 
00162   //  The second triangle to be split contains the point p0 but
00163   //    does not contain the point p1 as one of its points.
00164 
00165   uint k[4];
00166   k[0] = s;
00167   k[1] = neib;
00168   k[2] = n0;
00169   k[3] = n0+1;
00170 
00171   simplexD2linked *t;
00172   uint ki;
00173   for ( uint i=0; i<4; ++i )
00174   {
00175     ki=k[i];
00176     t = & vi[ki];
00177     if ( t->piInverseHas(p1) == true )
00178       continue;
00179     if ( t->piInverseHas(p0) == false )
00180       continue;
00181 
00182     split1D(ki,w0,w1);
00183 
00184     return;
00185   }
00186 
00187   assert(false);  // The case should have been handled.  
00188 }
00189 
00190 
00191 
00192 
00193 void d3tess::splitonboundarynoneighbor
00194 ( 
00195   uintc s,
00196   uintc j, 
00197   uintc w 
00198 )
00199 {
00200   // Two triangles produced from split.
00201 
00202   assert(w<pt.size());
00203   assert(w!=0);
00204   assert(s<vi.size());
00205 
00206   // Extract info from mesh.
00207 
00208   uint p[4];
00209   uint n[2];
00210 
00211   simplexD2linked & x(vi[s]);
00212 
00213   p[0] = x.pi[(j+1)%3];
00214   p[1] = x.pi[(j+2)%3];
00215   p[2] = x.pi[j];
00216   p[3] = w;
00217 
00218   assert(x.ni[j]==0);
00219 
00220   n[0] = x.ni[(j+1)%3];
00221   n[1] = x.ni[(j+2)%3];
00222 
00223   // Check the mesh before changing it.
00224   debugcheck();
00225 
00226   // Indexes to new triangles.
00227   uint k[2];
00228   k[0] = s;
00229   k[1] = vi.size();
00230 
00231   x =           simplexD2linked(p[1],p[2],p[3],k[1],0,n[0]);
00232   vi.push_back( simplexD2linked(p[3],p[2],p[0],n[1],0,k[0]) );
00233 
00234   if (n[1]!=0)
00235     vi[n[1]].changelink(s,k[1]);
00236 
00237   if (n[0]!=0)
00238     vi[n[0]].changelink(s,k[0]);
00239 
00240   debugcheck();
00241 }
00242 
00243 void d3tess::split1D( uintc s, uintc p0, uintc w0 )
00244 {
00245   assert(s<vi.size());
00246 
00247   uintc j = vi[s].piInverse(p0); 
00248 
00249   if (vi[s].ni[j]==0)
00250   {
00251     splitonboundarynoneighbor(s,j,w0);
00252     return;
00253   }
00254 
00255   // General Splitting on Boundary,
00256   //  four triangles produced.
00257 
00258   assert(w0<pt.size());
00259   assert(w0!=0);
00260 
00261   // Extract info from mesh.
00262 
00263   uint p[5];
00264   uint n[4];
00265 
00266   simplexD2linked & x(vi[s]);
00267   uint b = x.ni[j];
00268   assert(b!=0);
00269   simplexD2linked & y(vi[b]);
00270 
00271   assert( isconnected(s,b) );  
00272 
00273   uintc j2 = y.niInverse(s);
00274 
00275   p[0] = x.pi[(j+1)%3];
00276   p[1] = y.pi[j2];
00277   p[2] = x.pi[(j+2)%3];
00278   p[3] = x.pi[j];
00279   p[4] = w0;
00280 
00281   n[0] = x.ni[(j+1)%3];
00282   n[1] = x.ni[(j+2)%3];
00283   n[2] = y.ni[(j2+1)%3];
00284   n[3] = y.ni[(j2+2)%3];
00285 
00286   // Check the mesh before changing it.
00287   debugcheck();
00288 
00289   // Indexes to new triangles.
00290   uint k[4];
00291   k[0] = s;
00292   k[1] = b;
00293   k[2] = vi.size();
00294   k[3] = k[2]+1;
00295 
00296   x =           simplexD2linked(p[4],p[2],p[3],n[0],k[1],k[3]);
00297   y =           simplexD2linked(p[4],p[3],p[0],n[1],k[2],k[0]);
00298   vi.push_back( simplexD2linked(p[4],p[0],p[1],n[2],k[3],k[1]) );
00299   vi.push_back( simplexD2linked(p[4],p[1],p[2],n[3],k[0],k[2]) );
00300 
00301   if (n[0]!=0)
00302     vi[n[0]].changelink(s,k[0]);
00303 
00304   if (n[1]!=0)
00305     vi[n[1]].changelink(s,k[1]);
00306 
00307   if (n[2]!=0)
00308     vi[n[2]].changelink(b,k[2]);
00309 
00310   if (n[3]!=0)
00311     vi[n[3]].changelink(b,k[3]);
00312 
00313   debugcheck();
00314 }
00315 
00316 bool const d3tess::simplexdelete(uintc s)
00317 {
00318   if (s>=vi.size())
00319     return false;
00320 
00321   simplexD2linked & t(vi[s]);
00322 
00323   // If already deleted return true.
00324   if (t.isnull())
00325     return true;
00326 
00327   uint nb;
00328 
00329   // Visit each neighbor and unlink.
00330   for (int i=0; i<3; ++i)
00331   {
00332     nb = t.ni[i];
00333     if (nb!=0)
00334       vi[nb].changelink(s,0);
00335   }
00336 
00337   t.setnull();
00338 
00339   return true;
00340 }
00341 
00342 
00343 
00344 d3tess::~d3tess()
00345 {
00346   delete minimizer;
00347   minimizer=0;
00348 }
00349 
00350 d3tess::d3tess( uintc arrayMax )
00351   : 
00352   fan(*this), 
00353   minimizer( new d3minoperator(*this) ),
00354   debugenable(true)
00355 //  enablesplit(true),
00356 //  enablefan(true)
00357 { 
00358   pt.reserve(arrayMax);
00359   vi.reserve(arrayMax);
00360 
00361   reset();
00362 }
00363 
00364 void d3tess::initialize()
00365 {
00366   assert(pt.size()>3);
00367   assert(vi.size()==1);
00368 
00369   pt3c & p0(pt[1]);
00370   pt3c & p1(pt[2]);
00371   pt3c & p2(pt[3]);
00372 
00373   halfspaceD2< pt3, double > h(p1,p0);
00374   if (h.isInside(p2)==false)
00375     vi.push_back( simplexD2linked(1,2,3, 0,0,0) );
00376   else
00377     vi.push_back( simplexD2linked(3,2,1, 0,0,0) );
00378 }
00379 
00380 void d3tess::reset()
00381 {
00382   pt.clear();
00383   vi.clear();
00384 
00385   pt.push_back( pt3(0.0,0.0,0.0) );
00386   vi.push_back( simplexD2linked() );
00387 
00388   cp=1;
00389 }
00390 
00391 void d3tess::minimizerSet( d3minoperator* m)
00392 {
00393   assert(m!=0);
00394 
00395   delete minimizer;
00396   minimizer = m;
00397 }
00398 
00399 bool const d3tess::surfaceviewable(uintc k) const
00400 {
00401   simplexD2linked const & x(vi[cp]);
00402   halfspaceD2< pt3, double > h(pt[x.pi[vs.v[1]]],pt[x.pi[vs.v[0]]]);
00403   return h.isInside(pt[k]);
00404 }
00405   
00406   
00407 
00408 
00409 bool const d3tess::isconnected(uintc a, uintc b) const 
00410 {
00411 #ifndef NDEBUG
00412   uintc sz(vi.size());
00413   assert(a<sz);
00414   assert(b<sz);
00415 #endif
00416 
00417   //simplexD2linked const & A(vi[a]);
00418   //simplexD2linked const & B(vi[b]);
00419 
00420   if (vi[a].niInverseHas(b)==false)
00421     return false;
00422 
00423   if (vi[b].niInverseHas(a)==false)
00424     return false;
00425 
00426 /*
00427   bool res;
00428 
00429   A.niInverse(res,b);
00430   if (res==false)
00431     return false;
00432 
00433   B.niInverse(res,a);
00434   if (res==false)
00435     return false;
00436 */
00437 
00438   return true;
00439 }
00440 
00441 
00442  
00443 bool const d3tess::isconvex(uintc a, uintc b) const
00444 {
00445 #ifndef NDEBUG
00446   uintc sz(vi.size());
00447   assert(a<sz);
00448   assert(b<sz);
00449 #endif
00450 
00451   simplexD2linked const & A(vi[a]);
00452   simplexD2linked const & B(vi[b]);
00453 
00454   bool res;
00455 
00456   uint ai = A.niInverse(res,b);
00457   if (res==false)
00458     return false;
00459 
00460   uint bi = B.niInverse(res,a);
00461   if (res==false)
00462     return false;
00463 
00464   pt3 const & P0(pt[A.pi[ai]]);
00465   pt3 const & P1(pt[A.pi[(ai+1)%3]]);
00466   pt3 const & P2(pt[A.pi[(ai+2)%3]]);
00467 
00468 //cout << SHOW(P0) << " " << SHOW(P1) << " " << SHOW(P2) << endl;
00469 
00470   halfspaceD2< pt3, double > h1(P0,P1);
00471   halfspaceD2< pt3, double > h2(P2,P0);
00472 
00473   pt3 const & P3(pt[B.pi[bi]]);
00474 
00475   if (h1.isInside(P3)==false)
00476     return false;
00477   
00478   if (h2.isInside(P3)==false)
00479     return false;
00480 
00481   return true;
00482 }
00483 
00484 
00485 bool const d3tess::moveleft()
00486 {
00487   vs.clockwise();
00488 
00489   if (movedown()==false)
00490   {
00491     vs.anticlockwise();
00492     return false;
00493   }
00494 
00495   return true;
00496 }
00497 
00498 bool const d3tess::moveright()
00499 {
00500   vs.anticlockwise();
00501 
00502   if (movedown()==false)
00503   {
00504     vs.clockwise();
00505     return false;
00506   }
00507 
00508   return true;
00509 }
00510 
00511 bool const d3tess::movedown()
00512 {
00513   simplexD2linked const & x(vi[cp]);
00514 
00515   uint cp2 = x.ni[ vs.v[2] ];
00516   if (cp2==0)
00517     return false;
00518 
00519   simplexD2linked const &  y(vi[cp2]);
00520 
00521   uint yi = y.niInverse(cp);
00522   cp = cp2;
00523   vs.set(yi);
00524 
00525   return true;
00526 }
00527 
00528 bool const d3tess::boundaryorient()
00529 {
00530   simplexD2linked const & x(vi[cp]);
00531   
00532   for (uint i=0; i<3; ++i)
00533     if(x.ni[0]==0)
00534     {
00535       vs.set(i);
00536       return true;
00537     }
00538 
00539   return false;
00540 }
00541 
00542 simplexface const d3tess::cpsimplexfaceget() const
00543 { 
00544   assert(vs.validstate()); 
00545   return simplexface(cp,vs.v[2]); 
00546 }
00547 
00548 void d3tess::cpsimplexfaceset( simplexface const & sf)
00549 {
00550   cp = sf.id;
00551   vs.set(sf.face);
00552 }
00553 
00554 double const d3tess::cpbasemeasure() const
00555 {
00556   simplexD2linked const & x(vi[cp]);
00557 
00558   pt3 p0( pt[x.pi[vs.v[0]]]);
00559   pt3 p1( pt[x.pi[vs.v[1]]]);
00560   p0 -= p1;
00561 
00562   return p0.distance();
00563 }
00564 
00565 
00566 
00567 
00568 void d3tess::split2D( uintc w )
00569 {
00570   assert(w<pt.size());
00571   assert(w!=0);
00572 
00573   // Extract info from mesh.
00574 
00575   uint p[4];
00576   uint n[3];
00577 
00578 //cout << SHOW(pt[w]) << "  ";
00579 //cout << cpsimplex() << endl;
00580 
00581   simplexD2linked & x(vi[cp]);
00582   for (uint i=0; i<3; ++i)
00583   {
00584     p[i] = x.pi[i];
00585     n[i] = x.ni[i];
00586   }
00587   p[3] = w;
00588 
00589   debugcheck();
00590 
00591   // Indexes to new triangles.
00592   uint k[3];
00593   k[0] = cp;
00594   k[1] = vi.size();
00595   k[2] = k[1]+1;
00596 
00597   x =           simplexD2linked(p[3],p[1],p[2],n[0],k[1],k[2]);
00598   vi.push_back( simplexD2linked(p[3],p[2],p[0],n[1],k[2],k[0]) );
00599   vi.push_back( simplexD2linked(p[3],p[0],p[1],n[2],k[0],k[1]) );
00600 
00601   if (n[1]!=0)
00602     vi[n[1]].changelink(cp,k[1]);
00603 
00604   if (n[2]!=0)
00605     vi[n[2]].changelink(cp,k[2]);
00606 
00607   debugcheck();
00608 
00609   for (uint i=0; i<3; ++i)
00610   {
00611     if (n[i]==0)
00612       continue;
00613 
00614     assert(isconnected(n[i],k[i]));
00615   }
00616 
00617   for (uint i=0; i<3; ++i)
00618   {
00619     if (n[i]==0)
00620       continue;
00621 
00622     minimizer->eval(n[i],k[i]);
00623   }
00624 
00625   debugcheck();
00626 }
00627 
00628 
00629 
00630 
00631 void d3tess::addpoint(uintc k)
00632 {
00633 
00634   bool found = searchminimizetowardspoint(k);
00635   if (found)
00636   {
00637 
00638 //cout << "*1: " << SHOW(enablesplit) << endl;
00639 //    if (enablesplit==false)
00640 //      return;
00641 
00642 //cout << "*2" << endl;
00643     split2D(k);
00644 
00645     return;
00646   }
00647 
00648 
00649 //cout << "*3: " << SHOW(enablefan) << endl;
00650 //  if (enablefan==false);
00651 //    return;
00652 
00653 //cout << "*4" << endl;
00654 
00655   fan.eval(k);
00656 }
00657 
00658 bool const d3tess::searchminimizetowardspoint( uintc p )
00659 {
00660   // Statistics only.
00661   movecounter = 0;
00662 
00663   bool notfound = false;
00664   bool isinside = false;
00665   uint viewableface;
00666   for ( ; !notfound; )
00667     notfound = move_terminated(isinside,viewableface,p);
00668 
00669   if (isinside==false)
00670   {
00671     if (vs.v[2]!=viewableface)
00672       vs.anticlockwise();
00673     else
00674       return isinside;
00675 
00676     if (vs.v[2]!=viewableface)
00677       vs.anticlockwise();
00678     else
00679       return isinside;
00680 
00681     if (vs.v[2]!=viewableface)
00682       assert(false);
00683   }
00684   
00685   return isinside;
00686 }
00687 
00688 
00689 bool const d3tess::move_terminated
00690 (
00691   bool & insidetriangle,
00692   uint & viewableface,
00693   uintc p
00694 )
00695 {
00696   //For measuring statistics only.
00697   ++movecounter;
00698 
00699   simplexD2linked & x(vi[cp]);
00700 
00701   assert(p<pt.size());
00702   point3<double> const & target(pt[p]);
00703 
00704   trianglespace<pt3,double> t
00705   ( 
00706     pt[ x.pi[0] ],
00707     pt[ x.pi[1] ],
00708     pt[ x.pi[2] ]
00709   );
00710 
00711   // Is the point inside the triangle?
00712   if (!t.isInside(target))
00713   {
00714     insidetriangle=true;
00715 
00716     return true;
00717   }
00718 
00719   for ( uint i=0; i<3; ++i )
00720   {
00721     // Is the target viewable?
00722     if (t.hi[i].isInside(target))
00723     {
00724       if(x.ni[i]==0)
00725       {
00726         viewableface=i;
00727         return true;
00728       }
00729 
00730       // Move
00731       cp = x.ni[i];
00732 
00733       return false;
00734     }
00735   }
00736 
00737   assert(false);
00738 
00739   return false;
00740 }
00741 
00742 bool const d3tess::valid(uintc k) const
00743 {
00744   if (k>=vi.size())
00745     return false;
00746 
00747   if (vi[k].isnull())
00748     return true;
00749 
00750   // Look at each neighbor for links.
00751   for (uint i=0, nb; i<3; ++i)
00752   {
00753     nb = vi[k].ni[i];
00754     if (nb==0)
00755       continue;
00756 
00757     bool res;
00758 
00759     // Each point bordering neighbor must also be one
00760     // of the neighbors own points.
00761     for (uint w=0; w<3; ++w)
00762     {
00763       if (w==i)
00764         continue;
00765 
00766       vi[nb].piInverse( res, vi[k].pi[w] );
00767       if (res==false)
00768         return false;
00769     }
00770 
00771     // The neighbor must have a pointer back to k.
00772 
00773     if (vi[nb].niInverseHas(k)==false)
00774       return false;
00775 
00776 /*
00777     vi[nb].niInverse( res, k );
00778     if (res==false)
00779       return false;
00780 */
00781   }
00782 
00783   return true;
00784 }
00785 
00786 istream & d3tess::serializeInverse(istream & is)
00787 {
00788   pt.clear();
00789   vi.clear();
00790   cp=1;
00791 
00792   pt3 p;
00793 
00794   uint sz;
00795   is >> sz;
00796 
00797   uint k;
00798 
00799   for (uint i=0; i<sz; ++i)
00800   {
00801     is >> k;
00802     is >> p;
00803 
00804     pt.push_back(p);
00805   }
00806 
00807   simplexD2linked t;
00808 
00809   is >> sz;
00810   for (uint i=0; i<sz; ++i)
00811   {
00812     is >> k;
00813     is >> t;
00814 
00815     vi.push_back(t);
00816   }
00817 
00818   return is;
00819 }
00820 
00821 istream & operator >> (istream & is, d3tess & x)
00822 {
00823   return x.serializeInverse(is);
00824 }
00825 
00826 void d3tess::print(string & s) const
00827 {
00828   s="";
00829   uintc ptsz = pt.size();
00830   { stringstream ss; ss << ptsz; s+=(ss.str()+'\n'); }
00831 
00832   for (uint i=0; i<ptsz; ++i)
00833   {
00834     if (i<10)
00835       s += " ";
00836     if (i<100)
00837       s += " ";
00838     { stringstream ss; ss << i; s+=ss.str(); }
00839     s += ("  " + (string)(pt[i]) + '\n'); 
00840   }
00841 
00842   uintc visz = vi.size();
00843   { stringstream ss; ss << visz; s+=(ss.str()+'\n'); }
00844   for (uint i=0; i<visz; ++i)
00845   {
00846     if (i<10)
00847       s += " ";
00848     if (i<100)
00849       s += " ";
00850     { stringstream ss; ss << i; s+=ss.str(); }
00851     s += ("  " + (string)(vi[i]) + '\n');
00852   }
00853 }
00854 
00855 ostream & d3tess::print(ostream & os) const
00856 {
00857   uintc ptsz = pt.size();
00858   os << ptsz << endl;
00859 
00860   for (uint i=0; i<ptsz; ++i)
00861   {
00862     os << setw(2) << i;
00863     os << "  " << pt[i] << endl;
00864   }
00865 
00866   uintc visz = vi.size();
00867   os << visz << endl;
00868   for (uint i=0; i<visz; ++i)
00869   {
00870     os << setw(2) << i;
00871     os << "  " << vi[i] << endl;
00872   }
00873 
00874   return os;
00875 }
00876 
00877 ostream & operator << (ostream& os, d3tess const & x)
00878 {
00879   return x.print(os);
00880 }
00881 
00882 
00883 void d3tess::surfaceright()
00884 {
00885   assert( vi[cp].ni[ vs.v[2] ]==0 );
00886 
00887   if( vi[cp].ni[ vs.v[0] ]==0 )
00888   {
00889     vs.anticlockwise();
00890     return;
00891   }
00892   
00893   for ( ; moveright(); );
00894 
00895   vs.anticlockwise();
00896 }
00897 
00898 void d3tess::surfaceleft()
00899 {
00900   assert( vi[cp].ni[ vs.v[2] ]==0 );
00901 
00902   if( vi[cp].ni[ vs.v[1] ]==0 )
00903   {
00904     vs.clockwise();
00905     return;
00906   }
00907   
00908   for ( ; moveleft(); );
00909 
00910   vs.clockwise();
00911 }
00912 
00913 
00914 
00915 
00916 bool const d3tess::debugcheck() const 
00917 {
00918 
00919   if (debugenable==false)
00920     return true;
00921 
00922 // This function checks for correct links and
00923 // duplicate traingles.
00924 //
00925 // Another test that could be added is to check the
00926 // triangles winding. ie line(pi[0],pi[1]) to creat a halfplane h
00927 // left and including the line.  h sees p[2]. Include degenerate case
00928 // where all the points lie on the same line.
00929 
00930 #ifndef NDEBUG
00931 
00932 //cout << "DEBUG ON" << endl;
00933 
00934   bool res(true);
00935   uintc visz = vi.size();
00936 
00937   // Are the triangles unique.
00938   for (uint i=1; i<visz; ++i )
00939   {
00940     if ( vi[i].isnull() )
00941       continue;
00942 
00943     for (uint k=i+1; k<visz; ++k)
00944     {
00945       if (vi[i]==vi[k])
00946       {
00947         res=false;
00948 
00949         messageglobal() << "\n";
00950         messageglobal() << "error: triangles with the same points.\n";
00951         messageglobal() << "  check " << i << " " << k << "\n";
00952         messageglobal() << "vi[i]=" << vi[i] << "\n";
00953         messageglobal() << "vk[i]=" << vi[k] << "\n";
00954         messageglobal() << "\n";
00955         messageglobal() << *this;
00956       }
00957     }
00958   }
00959   assert(res==true);
00960 
00961   for (uint i=1; i<visz; ++i)
00962   {
00963     if ( vi[i].isnull() )
00964       continue;
00965 
00966     if(valid(i)==false)
00967     {
00968       res=false;
00969       messageglobal() << "error:  ";
00970       //messageglobal() << setw(2) << i;
00971       messageglobal() << "  " << vi[i] << "\n";
00972       messageglobal() << "Printing out tess." << "\n";
00973       messageglobal() << *this << "\n";
00974     }
00975   }
00976 
00977   assert(res==true);
00978 
00979   return res;
00980 
00981 #else
00982   return true;
00983 #endif
00984 
00985 }
00986 
00987 
00988 bool const d3tess::flip()
00989 {
00990   simplexD2linked & x(vi[cp]);
00991   uint b = x.ni[vs.v[2]];
00992 
00993   return flip(cp,b);
00994 }
00995 
00996 bool const d3tess::flip(uintc a, uintc b)
00997 {
00998 //cout << a << " " << b << " " << isconvex(a,b) << " | ";
00999   if (isconvex(a,b)==false)
01000     return false;
01001 
01002   simplexD2linked const & A(vi[a]);
01003   simplexD2linked const & B(vi[b]);
01004 
01005   // Have vs base bordering triangle b.
01006   uint ai = A.niInverse(b);
01007   cp=a;
01008   vs.set(ai);
01009 
01010   // Extract point and neighbor information
01011   // from the mesh.
01012 
01013   uint p[4];
01014 
01015   for (uint i=0; i<3; ++i)
01016     p[i] = A.pi[ vs.v[i] ];
01017   p[3] = B.pi[B.niInverse(a)];
01018 
01019   uint n[4];
01020   n[0] = A.ni[ vs.v[0] ];
01021   n[1] = A.ni[ vs.v[1] ];
01022   n[2] = B.ni[ B.piInverse(p[0]) ];
01023   n[3] = B.ni[ B.piInverse(p[1]) ];
01024 
01025 //for (uint i=0; i<4; ++i)
01026 //  cout << "p[" << i << "]=" << p[i] << " ";
01027 //cout << endl;
01028 
01029 //for (uint i=0; i<4; ++i)
01030 //  cout << "n[" << i << "]=" << n[i] << " ";
01031 //cout << endl;
01032 
01033   // Overwrite the previous triangles with new ones.
01034 
01035   uint k[2];
01036   k[0] = a;
01037   k[1] = b;
01038 
01039   vi[k[0]] = simplexD2linked(p[3],p[2],p[0],n[1],n[3],k[1]);
01040   vi[k[1]] = simplexD2linked(p[2],p[3],p[1],n[2],n[0],k[0]);
01041 
01042   // Relink neighbors to new triangles.
01043   //   Test if the neighbor exists before resetting.
01044   if (n[3]!=0)
01045     vi[n[3]].changelink(b,a);
01046   if (n[0]!=0)
01047     vi[n[0]].changelink(a,b);
01048 
01049   // Have vs base bordering b.
01050   ai = A.niInverse(b);
01051   cp=a;
01052   vs.set(ai);
01053 
01054   debugcheck();
01055 
01056   return true; 
01057 }
01058 
01059 
01060 
01061 void d3tess::viadd
01062 ( 
01063   uintc v0, uintc v1, uintc v2,
01064   uintc n0, uintc n1, uintc n2
01065 )
01066 { 
01067   vi.push_back( simplexD2linked(v0,v1,v2,n0,n1,n2) ); 
01068 }
01069 
01070 
01071 void d3tess::cppreserve(uint & cp0, virtualtriangle & vs0) const
01072 {
01073   cp0 = cp;
01074   vs0 = vs;
01075 }
01076 
01077 void d3tess::cppreserveInverse
01078 (
01079    uint const & cp0, 
01080    virtualtriangle const & vs0
01081 )
01082 {
01083   cp = cp0;
01084   vs = vs0;
01085 }
01086 
01087 
01088 d3tesspreserve::d3tesspreserve( d3tess & _tess)
01089   : tess(_tess)
01090 {  
01091   tess.cppreserve(cp0,vs0); 
01092 }
01093 
01094 d3tesspreserve::~d3tesspreserve()
01095 {
01096   tess.cppreserveInverse(cp0,vs0); 
01097 }
01098 
01099 
01100 
01101 
01102 
01103 
01104 

Generated on Fri Mar 4 00:49:26 2011 for Chelton Evans Source by  doxygen 1.5.8