proj home

Files   Classes   Functions   Hierarchy  

d4tess.cpp

Go to the documentation of this file.
00001 
00002 #include <cassert>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <vector>
00006 #include <set>
00007 #include <map>
00008 using namespace std;
00009 
00010 #include <point.h>
00011 #include <print.h>
00012 
00013 #include <d4tri.h>
00014 #include <d4tess.h>
00015 
00016 #include <tetrahedron.h>
00017 #include <tetrahedronpartition.h>
00018 #include <halfspaceD3.h>
00019 
00020 #include <d4fan.h>
00021 #include <message.h>
00022 
00023 typedef point4<double> pt4;
00024 typedef point4<double> const pt4c;
00025 
00026 
00027 void d4tess::getpoints
00028 ( 
00029   pt4 & P0, 
00030   pt4 & P1, 
00031   pt4 & P2, 
00032   pt4 & P3 
00033 ) const
00034 {
00035   d4tri const & x(cpsimplex());
00036 
00037 //messageglobal() << "cp=" << cp << "\n";
00038 //messageglobal() << "x=" << x << "\n";
00039 
00040   P0 = pt[ x.pi[ vs.v[0] ] ];
00041   P1 = pt[ x.pi[ vs.v[1] ] ];
00042   P2 = pt[ x.pi[ vs.v[2] ] ];
00043   P3 = pt[ x.pi[ vs.v[3] ] ];
00044 }
00045 
00046 
00047 d4tess::~d4tess()
00048 {
00049   delete minimizer;
00050   minimizer=0;
00051 }
00052 
00053 d4tess::d4tess( uintc arrayMax )
00054   : fan(*this), minimizer( new d4minoperator(*this) )
00055 { 
00056   pt.reserve(arrayMax);
00057   vi.reserve(arrayMax);
00058 
00059   reset();
00060 }
00061 
00062 void d4tess::minimizerSet( d4minoperator* m)
00063 {
00064   delete minimizer;
00065   minimizer = m;
00066 }
00067 
00068 
00069 void d4tess::viadd
00070 (
00071   uintc v0, uintc v1, uintc v2, uintc v3,
00072   uintc n0, uintc n1, uintc n2, uintc n3
00073 )
00074 {
00075   vi.push_back( d4tri(v0,v1,v2,v3,n0,n1,n2,n3) );
00076 }
00077 
00078 
00079 
00080 void d4tess::addpoint(uintc k)
00081 {
00082   uint face;
00083   bool found = searchinsidemesh(face,k);
00084 
00085   if (found)
00086     split(k);
00087   else
00088     fan.eval(k);
00089 
00090 }
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 boolc d4tess::surfaceviewable(uintc w) const
00103 {
00104   //d3halfspace<double> h
00105   halfspaceD3< pt4, double > h
00106   (
00107     pt[ vi[cp].pi[ vs.v[0] ] ],
00108     pt[ vi[cp].pi[ vs.v[1] ] ],
00109     pt[ vi[cp].pi[ vs.v[2] ] ]
00110   );
00111 
00112 assert(false);  // changed halfspace code.
00113   return h.isInside(pt[w]); 
00114 //  return h.eval(pt[w]);
00115 }
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 void d4tess::infiniteRecursion()
00125 {
00126   messageglobal() << "\n"; 
00127   messageglobal() << "*************************************************" << "\n";
00128   messageglobal() << "       Find the error." << "\n";
00129   messageglobal() << "\n";
00130   messageglobal() << *this << "\n";
00131   messageglobal() << "error:  Infinite Recursion has occured, see previous mesh." << "\n";
00132 }
00133 
00134 boolc d4tess::searchinsidemesh( uint & viewableface, uintc p )
00135 {
00136   bool notfound = false;
00137   bool isinside = false;
00138   for ( ; !notfound; )
00139     notfound = move_terminated(isinside,viewableface,p);
00140 
00141   if (isinside==false)
00142   {
00143     if (vs.v[3]!=viewableface)
00144       vs.left();
00145     else
00146       return isinside;
00147 
00148     if (vs.v[3]!=viewableface)
00149       vs.left();
00150     else
00151       return isinside;
00152 
00153     if (vs.v[3]!=viewableface)
00154       vs.right();
00155     else
00156       return isinside;
00157 
00158      
00159     if (vs.v[3]!=viewableface)
00160       assert(false);
00161   }
00162   
00163   return isinside;
00164 }
00165 
00166 boolc d4tess::move_terminated
00167 (
00168   bool & insidetetrahedron,
00169   uint & viewableface,
00170   uintc p
00171 )
00172 {
00173   d4tri & x(vi[cp]);
00174 
00175   assert(p<pt.size());
00176   pt4c & target(pt[p]);
00177 
00178   tetrahedronpartition< pt4, double > tp
00179   ( 
00180     pt[ x.pi[0] ],
00181     pt[ x.pi[1] ],
00182     pt[ x.pi[2] ],
00183     pt[ x.pi[3] ]
00184   );
00185 
00186   // Is the point inside the tetrahedron?
00187   if (tp.isInside(target))
00188   {
00189     insidetetrahedron=true;
00190 
00191     return true;
00192   }
00193 
00194   for ( uint i=0; i<4; ++i )
00195   {
00196     // Is the target viewable?
00197     if (tp.hi[i].isInside(target))
00198     {
00199       if(x.ni[i]==0)
00200       {
00201         viewableface=i;
00202         return true;
00203       }
00204 
00205       // Move
00206       cp = x.ni[i];
00207 
00208       return false;
00209       //i=4; // exit loop
00210     }
00211   }
00212 
00213   assert(false);
00214 
00215   return false;
00216 }
00217 
00218 
00219 void d4tess::debugprinttet(uintc k) const 
00220 {
00221   uint i;
00222   for (i=0; i<4; ++i)
00223     messageglobal() << vi[k].ni[i] << " ";
00224   messageglobal() << "\n";
00225 
00226   
00227   for (i=0; i<4; ++i)
00228     messageglobal() << vi[k].pi[i] << " ";
00229   messageglobal() << "\n";
00230 }
00231 
00232 
00233 // Four tetrahedrons from one.
00234 void d4tess::split( uintc k )
00235 {
00236   assert(k<pt.size());
00237   assert(k!=0);
00238 
00239   uintc w=cp;
00240 
00241 
00242 /*
00243   uintc n0 = vi[w].ni[0];
00244   uintc n1 = vi[w].ni[1];
00245   uintc n2 = vi[w].ni[2];
00246   uintc n3 = vi[w].ni[3];
00247 */
00248 
00249   uint n[4];
00250   uint p[4];
00251 
00252   for (uint i=0; i<4; ++i)
00253   {
00254     n[i] = vi[w].ni[i];
00255     p[i] = vi[w].pi[i];
00256   }
00257 
00258 /*
00259 
00260 messageglobal() << SHOW(n0) << " ";
00261 messageglobal() << SHOW(n1) << " ";
00262 messageglobal() << SHOW(n2) << " ";
00263 messageglobal() << SHOW(n3) << " "; 
00264 messageglobal() << "\n";
00265 
00266   uintc p0 = vi[w].pi[0];
00267   uintc p1 = vi[w].pi[1];
00268   uintc p2 = vi[w].pi[2];
00269   uintc p3 = vi[w].pi[3];
00270 
00271 messageglobal() << SHOW(p0) << " ";
00272 messageglobal() << SHOW(p1) << " ";
00273 messageglobal() << SHOW(p2) << " ";
00274 messageglobal() << SHOW(p3) << " "; 
00275 messageglobal() << "\n";
00276 */
00277 
00278   // Reference to three new consecutive tetrahedrons.
00279   // Which are the tetrahedrons opposite 0,1,2 of cp(before) respecitely.
00280   // The base tetrahedron w will now be the new cp.
00281   uintc z=vi.size();
00282 
00283   vi[w] =       d4tri(p[0],p[1],p[2],k,  z,z+1,z+2, n[3]);     // w:
00284 
00285   vi.push_back( d4tri(p[3],p[2],p[1],k,  w,z+2,z+1, n[0]) );   // z:
00286   vi.push_back( d4tri(p[3],p[0],p[2],k,  w,z,z+2,   n[1]) );   // z+1: 
00287   vi.push_back( d4tri(p[3],p[1],p[0],k,  w,z+1,z,   n[2]) );   // z+2
00288 
00289   if (n[0]!=0)
00290     vi[n[0]].niReset(cp,z);
00291   if (n[1]!=0)
00292     vi[n[1]].niReset(cp,z+1);
00293   if (n[2]!=0)
00294     vi[n[2]].niReset(cp,z+2);
00295 
00296 
00297 
00298     //vi[n0].ni[ vi[n0].niInverse(cp) ] = z;
00299 
00300 
00301 //  print(messageglobal());
00302 
00303 /*
00304 messageglobal() << vi[w] << "\n";
00305 messageglobal() << vi[z] << "\n";
00306 messageglobal() << vi[z+1] << " ";
00307 messageglobal() << vi[z+2] << " ";
00308 */
00309 
00310 /*
00311   if (n1!=0)
00312     vi[n1].ni[ vi[n1].niInverse(cp) ] = z+1;
00313   if (n2!=0)
00314     vi[n2].ni[ vi[n2].niInverse(cp) ] = z+2;
00315 */
00316 
00317   bool write_error(false);
00318 
00319   if (write_error)
00320   {
00321     messagefile e1("e1.txt",true); 
00322     e1() << *this;
00323   }
00324   debugcheck();
00325 
00326   if (n[0]!=0)
00327     minimizer->eval(n[0],z);
00328   if (write_error)
00329   {
00330     messagefile e2("e2.txt",true); 
00331     e2() << *this;
00332   }
00333   debugcheck();
00334 
00335   if (n[1]!=0)
00336     minimizer->eval(n[1],z+1);
00337   if (write_error)
00338   {
00339     messagefile e3("e3.txt",true); 
00340     e3() << *this;
00341   }
00342   debugcheck();
00343 
00344   if (n[2]!=0)
00345     minimizer->eval(n[2],z+2);
00346   if (write_error)
00347   {
00348     messagefile e4("e4.txt",true); 
00349     e4() << *this;
00350   }
00351   debugcheck();
00352 
00353   if (n[3]!=0)
00354     minimizer->eval(n[3],w);
00355   if (write_error)
00356   {
00357     messagefile e5("e5.txt",true); 
00358     e5() << *this;
00359   }
00360   debugcheck();
00361 }
00362 
00363 ostream & d4tess::print(ostream & os) const
00364 {
00365   uintc ptsz = pt.size();
00366   os << SHOW(ptsz) << "\n";
00367 
00368   for (uint i=1; i<ptsz; ++i)
00369   {
00370     os << setw(2) << i;
00371     os << "  " << pt[i] << "\n";
00372   }
00373 
00374   uintc visz = vi.size();
00375   os << SHOW(visz) << "\n";
00376   for (uint i=1; i<visz; ++i)
00377   {
00378     os << setw(2) << i;
00379     os << "  " << vi[i] << "\n";
00380   }
00381      
00382   return os;
00383 }
00384 
00385 
00386 boolc d4tess::valid(uintc k) const
00387 {
00388   if (k>=vi.size())
00389     return false;
00390 
00391   if (vi[k].isnull())
00392     return true;
00393 
00394   // Look at each neighbour for links.
00395   for (uint i=0, nb; i<4; ++i)
00396   {
00397     nb = vi[k].ni[i];
00398     if (nb==0)
00399       continue;
00400 
00401     bool res;
00402 
00403     // Each point bordering neighbour must also be one
00404     // of the neighbours own points.
00405     for (uint w=0; w<4; ++w)
00406     {
00407       if (w==i)
00408         continue;
00409 
00410       vi[nb].piInverse( res, vi[k].pi[w] );
00411       if (res==false)
00412         return false;
00413     }
00414 
00415     // The nieghbour must have a pointer back to k.
00416     vi[nb].niInverse( res, k );
00417     if (res==false)
00418       return false;
00419   }
00420 
00421   return true;
00422 }
00423 
00424 
00425 
00426 boolc d4tess::valid() const
00427 {
00428   bool res(true);
00429 
00430   uintc visz = vi.size();
00431   for (uint i=1; i<visz; ++i)
00432     res &= valid(i);
00433 
00434   return res;
00435 }
00436 
00437 boolc d4tess::debugcheck() const 
00438 {
00439 
00440 #ifndef NDEBUG
00441 
00442   bool res(true);
00443   uintc visz = vi.size();
00444 
00445   for (uint i=1; i<visz; ++i )
00446   {
00447     if ( vi[i].isnull() )
00448       continue;
00449     for (uint k=i+1; k<visz; ++k)
00450     {
00451       if (vi[i].hassamepoints( vi[k] ))
00452       {
00453         res=false;
00454 
00455         messageglobal() << "\n";
00456         messageglobal() << "error: tetrahedrons with the same points." << "\n";
00457         messageglobal() << "  check " << i << " " << k << "\n";
00458         messageglobal() << "vi[i]=" << vi[i] << "\n";
00459         messageglobal() << "vi[k]=" << vi[k] << "\n";
00460         messageglobal() << "\n";
00461         messageglobal() << *this;
00462       }
00463     }
00464   }
00465   assert(res==true);
00466 
00467   for (uint i=1; i<visz; ++i)
00468   {
00469     if(valid(i)==false)
00470     {
00471       res=false;
00472       messageglobal() << "error:  ";
00473       //messageglobal() << setw(2) << i;
00474       messageglobal() << " " << i;
00475       messageglobal() << "  " << vi[i] << "\n";
00476       messageglobal() << "Printing out tess." << "\n";
00477       messageglobal() << *this << "\n";
00478     }
00479   }
00480 
00481   assert(res==true);
00482 
00483   return res;
00484 
00485 #else
00486   return true;
00487 #endif
00488 
00489 }
00490 
00491 
00492 
00493 
00494 
00495 
00496 boolc d4tess::tetmovedown()
00497 {
00498   d4tri const & x(vi[cp]);
00499 
00500   uint cp2 = x.ni[ vs.v[2] ];
00501   if (cp2==0)
00502     return false;
00503 
00504   d4tri const &  y(vi[cp2]);
00505 
00506   uint a = y.piInverse( x.pi[vs.v[0]] );
00507   uint b = y.piInverse( x.pi[vs.v[1]] );
00508   uint c = y.piInverse( x.pi[vs.v[3]] );
00509   uint d = y.niInverse(cp);
00510 
00511   vs.set(a,b,c,d);
00512 
00513   cp = cp2;
00514 
00515   return true;
00516 }
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 boolc d4tess::tetmoveright()
00533 {
00534   d4tri const & x(vi[cp]);
00535 messageglobal() << x << "\n";
00536 
00537 messageglobal() << "vs.v[0]" << vs.v[0] << "\n";
00538 
00539   uint cp2 = x.ni[ vs.v[0] ];
00540 messageglobal() << "cp2=" << cp2 << "\n";
00541   if (cp2==0)
00542     return false;
00543 
00544   d4tri const &  y(vi[cp2]);
00545 
00546 messageglobal() << y << "\n";
00547 
00548   uint a = y.piInverse( x.pi[vs.v[1]] );
00549   uint b = y.piInverse( x.pi[vs.v[2]] );
00550   uint c = y.piInverse( x.pi[vs.v[3]] );
00551   uint d = y.niInverse(cp);
00552 
00553 
00554   messageglobal() << "a=" << a << " ";
00555   messageglobal() << "b=" << b << " ";
00556   messageglobal() << "c=" << c << " ";
00557   messageglobal() << "d=" << d << " ";
00558   messageglobal() << "\n";
00559 
00560   vs.set(a,b,c,d);
00561 
00562   cp = cp2;
00563 
00564   return true;
00565 }
00566 
00567 boolc d4tess::tetmoveleft()
00568 {
00569   d4tri const & x(vi[cp]);
00570 messageglobal() << x << "\n";
00571 
00572   uint cp2 = x.ni[ vs.v[1] ];
00573 messageglobal() << "cp2=" << cp2 << "\n";
00574   if (cp2==0)
00575     return false;
00576 
00577   d4tri const &  y(vi[cp2]);
00578 
00579 messageglobal() << y << "\n";
00580 
00581   uint a = y.piInverse( x.pi[vs.v[2]] );
00582   uint b = y.piInverse( x.pi[vs.v[0]] );
00583   uint c = y.piInverse( x.pi[vs.v[3]] );
00584   uint d = y.niInverse(cp);
00585 
00586 
00587   messageglobal() << "a=" << a << " ";
00588   messageglobal() << "b=" << b << " ";
00589   messageglobal() << "c=" << c << " ";
00590   messageglobal() << "d=" << d << " ";
00591   messageglobal() << "\n";
00592 
00593   vs.set(a,b,c,d);
00594 
00595   cp = cp2;
00596 
00597   return true;
00598 }
00599 
00600 void d4tess::surfacedown()
00601 {
00602   for ( ; tetmovedown(); );
00603 
00604   vs.right();
00605   vs.right();
00606   vs.anticlockwise();
00607 }
00608 
00609 void d4tess::surfaceleft()
00610 {
00611   vs.clockwise();
00612   surfacedown();
00613 }
00614 
00615 void d4tess::surfaceright()
00616 {
00617   vs.anticlockwise();
00618   surfacedown();
00619 }
00620 
00621 boolc d4tess::boundaryorient()
00622 {
00623   d4tri const & x(vi[cp]);
00624 
00625   // Transverse the virtual tetrahedrons surface.
00626 
00627   if (x.ni[ vs.v[3] ]==0)
00628     return true;
00629     
00630   vs.left();
00631   if (x.ni[ vs.v[3] ]==0)
00632     return true;
00633 
00634   vs.left();
00635   if (x.ni[ vs.v[3] ]==0)
00636     return true;
00637 
00638   vs.right();
00639   if (x.ni[ vs.v[3] ]==0)
00640     return true;
00641 
00642   return false;
00643 }
00644 
00645 
00646 ostream & operator << (ostream& os, d4tess const & x)
00647 { 
00648   return x.print(os); 
00649 }
00650 
00651 
00652 boolc d4tess::rotateaboutaxis(uint & steps)
00653 {
00654   steps=0;
00655 
00656   uint cp0 = cp;
00657 
00658   if (tetmovedown()==false)
00659     return false; 
00660 
00661   steps=1;
00662 
00663   for(;cp!=cp0; ++steps)
00664   {
00665     if (tetmovedown()==false)
00666       return false;
00667   }
00668 
00669   return true;
00670 }
00671 
00672 
00673 
00674 
00675 boolc d4tess::isconnected(uintc a, uintc b) const 
00676 {
00677   uintc sz(vi.size());
00678   assert(a<sz);
00679   assert(b<sz);
00680 
00681   d4tri const & A(vi[a]);
00682   d4tri const & B(vi[b]);
00683 
00684   bool res;
00685 
00686   A.niInverse(res,b);
00687   if (res==false)
00688     return false;
00689 
00690   B.niInverse(res,a);
00691   if (res==false)
00692     return false;
00693 
00694   return true;
00695 }
00696 
00697 
00698 boolc d4tess::isconvex( uintc a, uintc b ) const
00699 {
00700   assert(a<vi.size());
00701   assert(b<vi.size());
00702 
00703   assert(a!=0);
00704   assert(b!=0);
00705 
00706   d4tri const & A(vi[a]);
00707   d4tri const & B(vi[b]);
00708 
00709 //  if (isconnected(a,b)==false)
00710 //    return false;
00711 
00712 //  uint ai = A.niInverse(b);
00713 
00714   bool res;
00715   uint ai = A.niInverse(res,b);
00716   if (res==false)
00717     return false;
00718 
00719   uint bi = B.niInverse(res,a);
00720   if (res==false)
00721     return false;
00722 
00723 // KEEP THIS CODE   [KEEP]
00724 /*
00725 
00726   //  ASSUMING A CONVEX MESH
00727 
00728   //
00729   // This test may become more efficent as the
00730   //   mesh is better balanced.
00731   // At the moment it captures less than 10% of cases.
00732 
00733   for (uint i=0; i<4; ++i)
00734   {
00735     if (i==ai)
00736       continue;
00737 
00738     B.niInverse(res,A.ni[i]);
00739     if (res==true)
00740     {
00741 messageglobal() << "non-convex found with integer arithmetic" << " ";
00742       return false;
00743     }
00744   }
00745 
00746 messageglobal() << "normal convex test with halfplanes" << " ";
00747 
00748 */
00749 
00750 
00751 
00752   tetrahedronpartition< pt4, double > tp
00753   ( 
00754     pt[A.pi[0] ],
00755     pt[A.pi[1] ],
00756     pt[A.pi[2] ],
00757     pt[A.pi[3] ]
00758   );
00759 
00760   pt4 p(pt[B.pi[bi]]);
00761 
00762   for (uint i=0; i<4; ++i)
00763   {
00764     if (i==ai)
00765       continue;
00766 
00767     if ( tp.hi[i].isInside(p)==true )
00768       return false;
00769   }
00770 
00771   return true;
00772 }
00773 
00774 boolc d4tess::tet2to3()
00775 {
00776   d4tri & x(vi[cp]);
00777   uint b = x.ni[vs.v[3]];
00778 
00779   return tet2to3_(cp,b);
00780 }
00781 
00782 
00783 
00784 
00785 boolc d4tess::tet2to3_(uintc k1, uintc k2)
00786 {
00787   uintc z = vi.size();
00788   assert(k1<z);
00789   assert(k2<z);
00790 
00791   if ((k1==0)||(k2==0))
00792     return false;
00793 
00794 
00795 /*
00796 if (isconvex(k1,k2))
00797   messageglobal() << "convex " << k1 << " " << k2 << "\n";
00798 */
00799 
00800 
00801   if (isconvex(k1,k2)==false)
00802     return false;
00803 
00804   uint p[5];
00805   uint n[6];
00806   uint u[3];
00807 
00808   d4tri const & K1(vi[k1]);
00809   d4tri const & K2(vi[k2]);
00810 
00811   uintc k1i = K1.niInverse(k2);
00812   uintc k2i = K2.niInverse(k1);
00813   
00814   p[4] = K2.pi[k2i];
00815   p[0] = K1.pi[k1i];
00816 
00817 
00818   K2.getanticlockwiseface( u[0],u[1],u[2], k2i );
00819   for (uint i=0; i<3; ++i)
00820     p[i+1] = K2.pi[u[i]]; 
00821 
00822 //  n[3] = K2.ni[ u[2] ];
00823 //  n[4] = K2.ni[ u[0] ];
00824 //  n[5] = K2.ni[ u[1] ];
00825 
00826   n[3] = K2.ni[ K2.piInverse(p[3]) ];
00827   n[4] = K2.ni[ K2.piInverse(p[1]) ];
00828   n[5] = K2.ni[ K2.piInverse(p[2]) ];
00829 
00830   n[0] = K1.ni[ K1.piInverse(p[3]) ];
00831   n[1] = K1.ni[ K1.piInverse(p[1]) ];
00832   n[2] = K1.ni[ K1.piInverse(p[2]) ];
00833   
00834   d4tri a[3];
00835 
00836   a[0].construct( p[4],p[0],p[2],p[1],  n[0],n[3],z+2,z+1 ); 
00837   a[1].construct( p[0],p[4],p[2],p[3],  n[4],n[1],z+2,z ); 
00838   //a[2].construct( p[0],p[4],p[1],p[3],  n[5],n[2],z+1,z ); 
00839   a[2].construct( p[0],p[4],p[3],p[1],  n[5],n[2],z,z+1 ); 
00840 
00841   for (uint i=0; i<3; ++i)
00842     vi.push_back(a[i]);
00843 
00844   if( n[0]!=0)
00845     vi[n[0]].niReset(k1,z);
00846   if( n[3]!=0)
00847     vi[n[3]].niReset(k2,z);
00848   if( n[1]!=0)
00849     vi[n[1]].niReset(k1,z+1);
00850   if( n[4]!=0)
00851     vi[n[4]].niReset(k2,z+1);
00852   if( n[2]!=0)
00853     vi[n[2]].niReset(k1,z+2);
00854   if( n[5]!=0)
00855     vi[n[5]].niReset(k2,z+2);
00856 
00857   vi[k1].setnull();
00858   vi[k2].setnull();
00859 
00860   cp = z;
00861 
00862   return true;
00863 }
00864 
00865 
00866 boolc d4tess::tet2to3(uintc a, uintc b)
00867 {
00868 //assert(false);
00869   assert(a<vi.size());
00870   assert(b<vi.size());
00871 
00872   //messageglobal() << "a=" << a << " b=" << b << " convex " << isconvex(a,b) << "\n";
00873 
00874   if (isconvex(a,b)==false)
00875     return false;
00876 
00877   uint aj[5];
00878 
00879   d4tri const A(vi[a]);
00880   aj[0] = A.niInverse(b);
00881 
00882   d4tri const B(vi[b]);
00883   aj[4] = B.niInverse(a);
00884 
00885   A.getclockwiseface(aj[1],aj[2],aj[3],aj[0]);
00886 
00887   uint pj[5];
00888   for (uint i=0; i<4; ++i)
00889     pj[i] = A.pi[aj[i]];
00890   pj[4] = B.pi[aj[4]];
00891 
00892 /*
00893 for (uint i=0; i<5; ++i)
00894   messageglobal() << "aj[" << i << "]=" << aj[i] << " ";
00895 messageglobal() << "\n";
00896 for (uint i=0; i<5; ++i)
00897   messageglobal() << "pj[" << i << "]=" << pj[i] << " ";
00898 messageglobal() << "\n";
00899 */
00900 
00901 
00902 
00903   // nj[0] is ignored.
00904   // the indexes correspond with the points : the neighbour is opposite the point
00905   // with the same index.  For neighbours >3 simply subtract 3 and that is the
00906   // index for the second tetrahedron.
00907   uint nj[7];
00908   
00909   for (uint i=1; i<=3; ++i)
00910     nj[i] = A.ni[aj[i]];
00911 
00912   for (uint i=4; i<=6; ++i)
00913     nj[i] = B.ni[ B.piInverse(pj[i-3]) ];
00914 
00915 //for (uint i=1; i<=6; ++i)
00916 //  messageglobal() << "nj[" << i << "]=" << nj[i] << " ";
00917 //messageglobal() << "\n";
00918 
00919   uint k1(a), k2(b), k3(vi.size());
00920 
00921   vi[a] = d4tri( pj[0],pj[4],pj[2],pj[3], nj[4],nj[1],k3,k2 );
00922   vi[b] = d4tri( pj[4],pj[0],pj[2],pj[1], nj[3],nj[6],k3,k1 );
00923   vi.push_back( d4tri( pj[4],pj[0],pj[1],pj[3], nj[2],nj[5],k1,k2 ) );
00924 
00925   if (nj[1]!=0)
00926     vi[nj[1]].niReset(a,k1);
00927   if (nj[2]!=0)
00928     vi[nj[2]].niReset(a,k3);
00929   if (nj[3]!=0)
00930     vi[nj[3]].niReset(a,k2);
00931   if (nj[4]!=0)
00932     vi[nj[4]].niReset(b,k1);
00933   if (nj[5]!=0)
00934     vi[nj[5]].niReset(b,k3);
00935   if (nj[6]!=0)
00936     vi[nj[6]].niReset(b,k2);
00937 
00938   debugcheck();
00939 
00940   return true;
00941 }
00942 
00943 boolc d4tess::tet2to3Inverse()
00944 {
00945   uint steps;
00946   if (rotateaboutaxis(steps)==false)
00947     return false;
00948 
00949   if (steps!=3)
00950     return false;
00951 
00952   uint p[5];
00953   uint a[3];
00954   uint n[6];
00955 
00956   p[0] = vi[cp].pi[ vs.v[0] ];
00957   p[4] = vi[cp].pi[ vs.v[1] ];
00958 
00959   for (uint i=0; i<3; ++i)
00960   {
00961     a[i] = cp;
00962     p[i+1] = vi[cp].pi[ vs.v[2] ];
00963 
00964     n[i]   = vi[cp].ni[ vs.v[1] ];
00965     n[i+3] = vi[cp].ni[ vs.v[0] ];
00966 
00967     tetmovedown();
00968   }
00969 
00970   messageglobal() << "p[i]: ";
00971   for (uint i=0; i<5; ++i)
00972     messageglobal() << p[i] << " ";
00973   messageglobal() << "\n";
00974 
00975   messageglobal() << "n[i] ";
00976   for (uint i=0; i<6; ++i)
00977     messageglobal() << n[i] << " ";
00978   messageglobal() << "\n";
00979 
00980   messageglobal() << "a[i]" << "\n";
00981   for (uint i=0; i<3; ++i)
00982     messageglobal() << a[i] << ": " << vi[a[i]] << "\n";
00983   messageglobal() << "\n";
00984 
00985   uint k = vi.size();
00986   d4tri k1(p[1],p[3],p[2],p[0], n[1],n[0],n[2],k+1); 
00987   d4tri k2(p[1],p[2],p[3],p[4], n[4],n[5],n[3],k); 
00988 
00989   messageglobal() << "k1: " << k1 << "\n";
00990   messageglobal() << "k2: " << k2 << "\n";
00991 
00992   vi.push_back(k1);
00993   vi.push_back(k2);
00994 
00995   for (uint i=0; i<3; ++i)
00996     vi[a[0]] = vi[0];
00997 
00998   for (uint i=0; i<3; ++i)
00999   {
01000     if (n[i]!=0)
01001       vi[n[i]].niReset(a[i],k);
01002 
01003     if (n[i+3]!=0)
01004       vi[n[i+3]].niReset(a[i],k+1);
01005 
01006     vi[a[i]].setnull();
01007   }
01008 
01009   cp = k;
01010 
01011   debugcheck();
01012 
01013 
01014   // Rotating about an axis with three tetrahedrons
01015   // is always a convex shape.
01016   return true;
01017 }
01018 
01019 simplexface const d4tess::cpsimplexface() const
01020 { 
01021   assert(vs.validstate()); 
01022   return simplexface(cp,vs.v[3]); 
01023 }
01024 
01025 void d4tess::reset()
01026 {
01027   pt.clear();
01028   vi.clear();
01029 
01030   pt.push_back( pt4(0.0,0.0,0.0,0.0) );
01031   vi.push_back( d4tri() );
01032 
01033   cp=1;
01034 }
01035 
01036 void d4tess::initialize()
01037 {
01038   assert(pt.size()>4);
01039   assert(vi.size()==1);
01040 
01041   pt4c & p0(pt[1]);
01042   pt4c & p1(pt[2]);
01043   pt4c & p2(pt[3]);
01044   pt4c & p3(pt[4]);
01045 
01046   halfspaceD3< pt4, double > h(p2,p1,p0);
01047   if (h.isInside(p3)==false)
01048     vi.push_back( d4tri(1,2,3,4, 0,0,0,0) );
01049   else
01050     vi.push_back( d4tri(4,3,2,1, 0,0,0,0) );
01051 }
01052 
01053 
01054 
01055 
01056 
01057 
01058 
01059 

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