Files Classes Functions Hierarchy
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
1.5.8