Files Classes Functions Hierarchy
00001 00002 #include <cassert> 00003 #include <cstdlib> 00004 00005 #include <GL/glut.h> 00006 #include <GL/gl.h> 00007 00008 using namespace std; 00009 00010 #include <gobj.h> 00011 #include <pointsdisplay.h> 00012 #include <triangle.h> 00013 #include <random.h> 00014 00015 #include <d3tessdraw.h> 00016 00017 #define SHOW(x) #x << '=' << (x) 00018 00019 typedef unsigned int uint; 00020 typedef unsigned int const uintc; 00021 typedef point3<double> pt3; 00022 typedef point2<double> pt2; 00023 00024 00025 void writesurfaceobj::draw() 00026 { 00027 surfacecolor.draw(); 00028 00029 uintc imax = tess.vi.size(); 00030 for (uint i=1; i<imax; ++i) 00031 { 00032 simplexD2linked t(tess.vi[i]); 00033 00034 if (t.isnull()) 00035 continue; 00036 00037 pt3c & P0(tess.pt[t.pi[0]]); 00038 pt3c & P1(tess.pt[t.pi[1]]); 00039 pt3c & P2(tess.pt[t.pi[2]]); 00040 00041 surface.eval(P0,P1,P2); 00042 } 00043 } 00044 00045 00046 void writepointsobj::draw() 00047 { 00048 gobjContainer & x = * gobjContainer::global; 00049 00050 x.push( new gobjglPushAttrib(GL_CURRENT_BIT) ); 00051 x.push( new gobjglPushAttrib(GL_LIGHTING_BIT) ); 00052 00053 x.push( new gobjglDisable(GL_LIGHTING) ); 00054 00055 x.push( new gobjglColor3ub(col) ); 00056 00057 //displaypoints<pt3> dp(x,tess.pt); 00058 pointsdisplay2D<pt3> dp(x,tess.pt); 00059 00060 x.push( new gobjglPopAttrib() ); 00061 x.push( new gobjglPopAttrib() ); 00062 } 00063 00064 00065 00066 void writewindingobj::draw() 00067 { 00068 glPushAttrib(GL_CURRENT_BIT); 00069 glPushAttrib(GL_LIGHTING_BIT); 00070 00071 glBegin(GL_LINES); 00072 00073 uintc imax = tess.vi.size(); 00074 for (uint i=1; i<imax; ++i) 00075 { 00076 simplexD2linked t(tess.vi[i]); 00077 00078 if (t.isnull()) 00079 continue; 00080 00081 pt3c & P0(tess.pt[t.pi[0]]); 00082 pt3c & P1(tess.pt[t.pi[1]]); 00083 00084 glColor3ub(255,0,0); 00085 glVertex2f(P0.x,P0.y); 00086 glColor3ub(0,255,0); 00087 glVertex2f(P1.x,P1.y); 00088 00089 } 00090 00091 glEnd(); 00092 00093 glPopAttrib(); 00094 glPopAttrib(); 00095 } 00096 00097 00098 00099 void writegridobj::draw() 00100 { 00101 glPushAttrib(GL_CURRENT_BIT); 00102 glPushAttrib(GL_LIGHTING_BIT); 00103 00104 gridcolor.draw(); 00105 00106 vector<pt3> const & pt(tess.pt); 00107 vector<simplexD2linked> const & vi(tess.vi); 00108 00109 glBegin(GL_LINES); 00110 00111 uintc imax = tess.vi.size(); 00112 for (uint i=1; i<imax; ++i) 00113 { 00114 simplexD2linked const & t(vi[i]); 00115 00116 if (t.isnull()) 00117 continue; 00118 00119 pt3c & P0(pt[t.pi[0]]); 00120 pt3c & P1(pt[t.pi[1]]); 00121 pt3c & P2(pt[t.pi[2]]); 00122 00123 glVertex2f(P0.x,P0.y); 00124 glVertex2f(P1.x,P1.y); 00125 glVertex2f(P0.x,P0.y); 00126 glVertex2f(P2.x,P2.y); 00127 glVertex2f(P1.x,P1.y); 00128 glVertex2f(P2.x,P2.y); 00129 00130 } 00131 00132 glEnd(); 00133 00134 glPopAttrib(); 00135 glPopAttrib(); 00136 } 00137 00138 00139 void writesimplicesobj::draw() 00140 { 00141 gobjContainer & x = * gobjContainer::global; 00142 00143 x.push( new gobjglPushAttrib(GL_CURRENT_BIT) ); 00144 x.push( new gobjglPushAttrib(GL_LIGHTING_BIT) ); 00145 00146 x.push( new gobjglDisable(GL_LIGHTING) ); 00147 00148 x.push( new gobjglColor3f(1.0,0.0,0.0) ); 00149 00150 uintc n = tess.vi.size(); 00151 vector< pt3 > v; 00152 uint k; 00153 pt3 w; 00154 00155 // The first tet is void. 00156 v.push_back(w); 00157 00158 for (uint i=1; i<n; ++i) 00159 { 00160 simplexD2linked const & t(tess.vi[i]); 00161 w = pt3(); 00162 00163 for (k=0; k<3; ++k) 00164 w += tess.pt[ t.pi[k] ]; 00165 00166 w *= 0.3333333333333; 00167 v.push_back(w); 00168 } 00169 00170 //displaypoints<pt3> dp(x,v,false); 00171 pointsdisplay2D<pt3> dp(x,v,false); 00172 00173 x.push( new gobjglPopAttrib() ); 00174 x.push( new gobjglPopAttrib() ); 00175 } 00176 00177 00178 00179 void writecpobj::draw() 00180 { 00181 glPushAttrib(GL_CURRENT_BIT); 00182 glPushAttrib(GL_LIGHTING_BIT); 00183 00184 simplexD2linked const & cp(tess.cpsimplex()); 00185 virtualtriangle const & vs(tess.vs); 00186 00187 pt3 P0(tess.pt[ cp.pi[vs.v[0]] ]); 00188 pt3 P1(tess.pt[ cp.pi[vs.v[1]] ]); 00189 pt3 P2(tess.pt[ cp.pi[vs.v[2]] ]); 00190 00191 float const blendratio = 0.85; 00192 00193 glBegin(GL_TRIANGLES); 00194 00195 00196 /* 00197 glColor3ub(255,0,0); 00198 glVertex2f(P0.x,P0.y); 00199 glVertex2f(P1.x,P1.y); 00200 glColor3ub(0,255,0); 00201 glVertex2f(P2.x,P2.y); 00202 */ 00203 00204 glColor4f(1.0,0.0,0.0,blendratio); 00205 glVertex2f(P0.x,P0.y); 00206 glVertex2f(P1.x,P1.y); 00207 glColor4f(0.0,1.0,0.0,blendratio); 00208 glVertex2f(P2.x,P2.y); 00209 00210 glColor4f(1.0,156.0/255.0,0.0,blendratio); 00211 // glColor3ub(255,165,0); 00212 00213 for (uint i=0; i<3; ++i) 00214 { 00215 if (cp.ni[i]==0) 00216 continue; 00217 00218 simplexD2linked const & nb(tess.vi[cp.ni[i]]); 00219 00220 pt3 const & P0(tess.pt[ nb.pi[0] ]); 00221 pt3 const & P1(tess.pt[ nb.pi[1] ]); 00222 pt3 const & P2(tess.pt[ nb.pi[2] ]); 00223 00224 glVertex2f(P0.x,P0.y); 00225 glVertex2f(P1.x,P1.y); 00226 glVertex2f(P2.x,P2.y); 00227 } 00228 00229 glEnd(); 00230 00231 glPopAttrib(); 00232 glPopAttrib(); 00233 00234 } 00235 00236 00237 void writecpvoronoiobj::onevertex() const 00238 { 00239 uint cp0; 00240 virtualtriangle vs0; 00241 tess.cppreserve(cp0,vs0); 00242 00243 vector<pt3> const & pt(tess.pt); 00244 00245 simplexD2linked const & w(tess.cpsimplex()); 00246 00247 pt2 p0; 00248 triangle< pt2, double > t 00249 ( 00250 pt[w.pi[0]], 00251 pt[w.pi[1]], 00252 pt[w.pi[2]] 00253 ); 00254 //t.midpointcirclecenter(p0); 00255 t.circumcenter(p0); 00256 00257 pt2 p1; 00258 pt2 p2; 00259 00260 bool res=true; 00261 p1 = p0; 00262 for ( ; tess.moveleft() && res; ) 00263 { 00264 simplexD2linked const & w(tess.cpsimplex()); 00265 00266 triangle< pt2, double > t 00267 ( 00268 pt[w.pi[0]], 00269 pt[w.pi[1]], 00270 pt[w.pi[2]] 00271 ); 00272 00273 //t.midpointcirclecenter(p2); 00274 t.circumcenter(p2); 00275 00276 glVertex2d(p1.x,p1.y); 00277 glVertex2d(p2.x,p2.y); 00278 00279 p1 = p2; 00280 00281 // Is the vertex a vertex within the mesh. 00282 if (tess.cp==cp0) 00283 { 00284 tess.cppreserveInverse(cp0,vs0); 00285 return; 00286 } 00287 } 00288 00289 tess.cppreserveInverse(cp0,vs0); 00290 tess.vs.clockwise(); 00291 00292 p1 = p0; 00293 for ( ; tess.moveright() && res; ) 00294 { 00295 simplexD2linked const & w(tess.cpsimplex()); 00296 00297 triangle< pt2, double > t 00298 ( 00299 pt[w.pi[0]], 00300 pt[w.pi[1]], 00301 pt[w.pi[2]] 00302 ); 00303 00304 //t.midpointcirclecenter(p2); 00305 t.circumcenter(p2); 00306 00307 glVertex2d(p1.x,p1.y); 00308 glVertex2d(p2.x,p2.y); 00309 00310 p1 = p2; 00311 00312 // There should be no possibility of an infinite loop. 00313 } 00314 00315 tess.cppreserveInverse(cp0,vs0); 00316 } 00317 00318 00319 00320 void writecpvoronoiobj::draw() 00321 { 00322 00323 //gresPushAttribPopAttrib att1(GL_CURRENT_BIT); 00324 myglPushAttrib att1(GL_CURRENT_BIT); 00325 //gresPushAttribPopAttrib att2(GL_LIGHTING_BIT); 00326 myglPushAttrib att2(GL_LIGHTING_BIT); 00327 00328 glColor3ub(0,255,0); 00329 00330 glDisable(GL_LIGHTING); 00331 00332 //gresEnableDisable enabledisable(GL_LINE_STIPPLE); 00333 myglCapability cap1(GL_LINE_STIPPLE); 00334 00335 glLineStipple(1,0x00FF); 00336 00337 00338 //gresBeginEnd begend(GL_LINES); 00339 myglMode m1(GL_LINES); 00340 00341 onevertex(); 00342 tess.vs.clockwise(); 00343 onevertex(); 00344 tess.vs.clockwise(); 00345 onevertex(); 00346 tess.vs.clockwise(); 00347 00348 } 00349 00350 00351 void writevoronoidiagramobj::draw() 00352 { 00353 00354 // Construct a one to one mapping between a point 00355 // and one of its bordering simplices. 00356 00357 vector<pt3> const & pt(tess.pt); 00358 uint psz = pt.size(); 00359 uint * fp = new unsigned int[psz]; 00360 for (uint i=0; i<psz; ++i) 00361 fp[i] = 0; 00362 00363 vector<simplexD2linked> const & vi(tess.vi); 00364 uint vsz = tess.vi.size(); 00365 00366 uint k; 00367 uint p1; 00368 for (uint i=1; i<vsz; ++i) 00369 { 00370 if (vi[i].isnull()) 00371 continue; 00372 00373 for (k=0; k<3; ++k) 00374 { 00375 p1 = vi[i].pi[k]; 00376 if (fp[p1]!=0) 00377 continue; 00378 00379 fp[p1] = i; 00380 } 00381 } 00382 00383 d3tesspreserve preservecp(tess); 00384 00385 // Use the mapping to construct the voronoi regions by 00386 // rotating about the point. 00387 00388 gobjContainer & x = * gobjContainer::global; 00389 00390 x.push( new gobjglPushAttrib(GL_CURRENT_BIT) ); 00391 x.push( new gobjglPushAttrib(GL_LIGHTING_BIT) ); 00392 00393 x.push( new gobjglDisable(GL_LIGHTING) ); 00394 00395 x.push( new gobjglColor3f(0.0,1.0,0.0) ); 00396 00397 x.push( new gobjglEnable(GL_LINE_STIPPLE) ); 00398 00399 x.push( new gobjglLineStipple(1,0x00FF) ); 00400 00401 x.push( new gobjglBegin(GL_LINES) ); 00402 00403 // Draw voronoi polygons. 00404 for (uint i=1; i<psz; ++i) 00405 { 00406 if (fp[i]==0) 00407 { 00408 cout << "error: point " << i << " has no triangle" << endl; 00409 continue; 00410 } 00411 00412 // Let the point i be in the bottom right hand corner of 00413 // vs's orientation. 00414 tess.cp = fp[i]; 00415 tess.vs.set( vi[ fp[i] ].piInverse(i)); 00416 tess.vs.clockwise(); 00417 onevertex(); 00418 } 00419 00420 x.push( new gobjglEnd() ); 00421 00422 x.push( new gobjglDisable(GL_LINE_STIPPLE) ); 00423 00424 x.push( new gobjglPopAttrib() ); 00425 x.push( new gobjglPopAttrib() ); 00426 00427 delete[] fp; 00428 } 00429 00430 00431 00432 00433 00434 // Does not preserve cp or orientation. 00435 void writevoronoidiagramobj::onevertex() const 00436 { 00437 uint cp0; 00438 virtualtriangle vs0; 00439 tess.cppreserve(cp0,vs0); 00440 00441 vector<pt3> const & pt(tess.pt); 00442 00443 simplexD2linked const & w(tess.cpsimplex()); 00444 00445 pt2 p0; 00446 triangle< pt2, double > t 00447 ( 00448 pt[w.pi[0]], 00449 pt[w.pi[1]], 00450 pt[w.pi[2]] 00451 ); 00452 //t.midpointcirclecenter(p0); 00453 t.circumcenter(p0); 00454 00455 pt2 p1; 00456 pt2 p2; 00457 00458 gobjContainer & x = * gobjContainer::global; 00459 00460 bool res=true; 00461 p1 = p0; 00462 for ( ; tess.moveleft() && res; ) 00463 { 00464 simplexD2linked const & w(tess.cpsimplex()); 00465 00466 triangle< pt2, double > t 00467 ( 00468 pt[w.pi[0]], 00469 pt[w.pi[1]], 00470 pt[w.pi[2]] 00471 ); 00472 00473 //t.midpointcirclecenter(p2); 00474 t.circumcenter(p2); 00475 00476 x.push( new gobjglVertex2d(p1.x,p1.y) ); 00477 x.push( new gobjglVertex2d(p2.x,p2.y) ); 00478 00479 p1 = p2; 00480 00481 // Is the vertex a vertex within the mesh. 00482 if (tess.cp==cp0) 00483 return; 00484 } 00485 00486 tess.cppreserveInverse(cp0,vs0); 00487 tess.vs.clockwise(); 00488 00489 p1 = p0; 00490 for ( ; tess.moveright() && res; ) 00491 { 00492 simplexD2linked const & w(tess.cpsimplex()); 00493 00494 triangle< pt2, double > t 00495 ( 00496 pt[w.pi[0]], 00497 pt[w.pi[1]], 00498 pt[w.pi[2]] 00499 ); 00500 00501 //t.midpointcirclecenter(p2); 00502 t.circumcenter(p2); 00503 00504 x.push( new gobjglVertex2d(p1.x,p1.y) ); 00505 x.push( new gobjglVertex2d(p2.x,p2.y) ); 00506 00507 p1 = p2; 00508 00509 // There should be no possibility of an infinite loop. 00510 } 00511 } 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 00524 00525 00526 00527 void writecpcircleobj::draw() 00528 { 00529 glPushAttrib(GL_CURRENT_BIT); 00530 glPushAttrib(GL_LIGHTING_BIT); 00531 00532 glColor3ub(255,0,0); 00533 00534 glDisable(GL_LIGHTING); 00535 00536 simplexD2linked const & cp(tess.cpsimplex()); 00537 00538 pt3 const & P0(tess.pt[ cp.pi[0] ]); 00539 pt3 const & P1(tess.pt[ cp.pi[1] ]); 00540 pt3 const & P2(tess.pt[ cp.pi[2] ]); 00541 00542 triangle< pt2, double > t(P0,P1,P2); 00543 pt2 p0; 00544 double radius; 00545 //t.outercircle(p0,radius); 00546 t.outercircle(radius,p0); 00547 gobjMyCircleDraw(radius, pt3(p0), cir).draw(); 00548 00549 /* 00550 // Attempt to look at neighbours but the situation 00551 // becomes more complicated. 00552 glColor3ub(255,165,0); 00553 00554 for (uint i=0; i<3; ++i) 00555 { 00556 if (cp.ni[i]==0) 00557 continue; 00558 00559 simplexD2linked const & nb(tess.vi[cp.ni[i]]); 00560 00561 pt3 const & P0(tess.pt[ nb.pi[0] ]); 00562 pt3 const & P1(tess.pt[ nb.pi[1] ]); 00563 pt3 const & P2(tess.pt[ nb.pi[2] ]); 00564 00565 triangle<double> t(P0,P1,P2); 00566 t.outercircle(p0,radius); 00567 gobjMyCircleDraw(radius, pt3(p0), cir).draw(); 00568 } 00569 */ 00570 00571 glPopAttrib(); 00572 glPopAttrib(); 00573 } 00574 00575 void writecirclesobj::draw() 00576 { 00577 glPushAttrib(GL_CURRENT_BIT); 00578 glPushAttrib(GL_LIGHTING_BIT); 00579 00580 pt2 p0; 00581 double radius; 00582 00583 vector<pt3> const & pt(tess.pt); 00584 00585 vector<simplexD2linked> const & vi(tess.vi); 00586 00587 glColor3ub(255,0,0); 00588 00589 uint imax = vi.size(); 00590 for (uint i=0; i<imax; ++i) 00591 { 00592 if (vi[i].isnull()) 00593 continue; 00594 00595 // Difficult to see multicolored circles. 00596 //glColor3ub(rand() % 256,rand() % 256,rand() % 256); 00597 00598 triangle< pt2, double > t 00599 ( 00600 pt[vi[i].pi[0]], 00601 pt[vi[i].pi[1]], 00602 pt[vi[i].pi[2]] 00603 ); 00604 //t.outercircle(p0,radius); 00605 t.outercircle(radius,p0); 00606 gobjMyCircleDraw(radius, pt3(p0), cir).draw(); 00607 } 00608 00609 glPopAttrib(); 00610 glPopAttrib(); 00611 } 00612 00613 00614 void writemulticolorobj::draw() 00615 { 00616 gobjContainer & x = * gobjContainer::global; 00617 00618 x.push( new gobjglPushAttrib(GL_CURRENT_BIT) ); 00619 x.push( new gobjglPushAttrib(GL_LIGHTING_BIT) ); 00620 00621 x.push( new gobjglDisable(GL_LIGHTING) ); 00622 00623 x.push( new gobjglBegin(GL_TRIANGLES) ); 00624 00625 float const blendratio = 0.5; 00626 00627 random11<double> r; 00628 00629 vector< pt3 > const & pt(tess.pt); 00630 vector<simplexD2linked> const & vi(tess.vi); 00631 00632 uintc imax = tess.vi.size(); 00633 for (uint i=1; i<imax; ++i) 00634 { 00635 simplexD2linked const & t(vi[i]); 00636 00637 if (t.isnull()) 00638 continue; 00639 00640 x.push( new gobjglColor4f(r(),r(),r(),blendratio) ); 00641 00642 pt3c & P0(pt[t.pi[0]]); 00643 pt3c & P1(pt[t.pi[1]]); 00644 pt3c & P2(pt[t.pi[2]]); 00645 00646 x.push( new gobjglVertex2f(P0.x,P0.y) ); 00647 x.push( new gobjglVertex2f(P1.x,P1.y) ); 00648 x.push( new gobjglVertex2f(P2.x,P2.y) ); 00649 00650 } 00651 00652 x.push( new gobjglEnd() ); 00653 00654 x.push( new gobjglPopAttrib() ); 00655 x.push( new gobjglPopAttrib() ); 00656 } 00657 00658 00659 00660 /* 00661 void d3tessdraw::writewinding() const 00662 { 00663 glPushAttrib(GL_CURRENT_BIT); 00664 glPushAttrib(GL_LIGHTING_BIT); 00665 00666 glBegin(GL_LINES); 00667 00668 uintc imax = tess.vi.size(); 00669 for (uint i=1; i<imax; ++i) 00670 { 00671 simplexD2linked t(tess.vi[i]); 00672 00673 if (t.isnull()) 00674 continue; 00675 00676 pt3c & P0(tess.pt[t.pi[0]]); 00677 pt3c & P1(tess.pt[t.pi[1]]); 00678 00679 glColor3ub(255,0,0); 00680 glVertex2f(P0.x,P0.y); 00681 glColor3ub(0,255,0); 00682 glVertex2f(P1.x,P1.y); 00683 00684 } 00685 00686 glEnd(); 00687 00688 glPopAttrib(); 00689 glPopAttrib(); 00690 } 00691 */ 00692 00693 00694 00695 00696 00697 00698 void d3tessdraw::meshupdate() 00699 { 00700 gdynamic.nuke(); 00701 00702 assert(gobjContainer::global!=0); 00703 // Save the current global graphics stream. 00704 gobjContainer & g(*gobjContainer::global); 00705 00706 // Make this the new graphics stream. 00707 gdynamic.set(); 00708 00709 // Writes all the graphics to gobjContainer::global 00710 graphicsDeffered.draw(); 00711 00712 // Restore global graphics stream. 00713 g.set(); 00714 } 00715 00716 00717 d3tessdraw::d3tessdraw( d3tess & tess_ ) 00718 : tess(tess_), gdynamic(true), graphicsDeffered(true), 00719 graphicsImmediate(true) 00720 { 00721 //gobjContainer::global->push_back(&gdynamic); 00722 00723 graphicsDeffered.push(new writepointsobj(tess)); 00724 graphicsDeffered.push(new writesimplicesobj(tess)); 00725 graphicsDeffered.push(new writemulticolorobj(tess)); 00726 graphicsDeffered.push(new writevoronoidiagramobj(tess)); 00727 00728 graphicsImmediate.push(new writewindingobj(tess)); 00729 graphicsImmediate.push(new writegridobj(tess)); 00730 graphicsImmediate.push(new writecpobj(tess)); 00731 graphicsImmediate.push(new writesurfaceobj(tess)); 00732 graphicsImmediate.push(new writecpcircleobj(tess)); 00733 graphicsImmediate.push(new writecirclesobj(tess)); 00734 graphicsImmediate.push(new writecpvoronoiobj(tess)); 00735 00736 glDisable(GL_DEPTH_TEST); 00737 glEnable(GL_BLEND); 00738 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00739 00740 meshupdate(); 00741 } 00742 00743 00744 void d3tessdraw::draw() 00745 { 00746 00747 glPushAttrib(GL_CURRENT_BIT); 00748 glPushAttrib(GL_LIGHTING_BIT); 00749 00750 graphicsImmediate.draw(); 00751 gdynamic.draw(); 00752 00753 glPopAttrib(); 00754 glPopAttrib(); 00755 } 00756 00757 00758
1.5.8