proj home

Files   Classes   Functions   Hierarchy  

d3tessdraw.cpp

Go to the documentation of this file.
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 

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