Main Page   Namespace List   Compound List   File List   Compound Members   File Members  

Timestep.C

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003 Eric Bohm
00003  *
00004  *This program is free software; you can redistribute it and/or modify
00005  *it under the terms of the GNU General Public License as published by
00006  *the Free Software Foundation version 2 of the License.
00007  * 
00008  *This program is distributed in the hope that it will be useful, but
00009  *WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  *General Public License for more details.
00012  * 
00013  *You should have received a copy of the GNU General Public License along
00014  *with this program; if not, write to the Free Software Foundation, Inc.,
00015  *675 Mass Ave, Cambridge, MA 02139, USA.
00016  *
00017  */
00018 
00019 using namespace std;
00020 #include <GL/glut.h>
00021 #include <stdio.h>
00022 #include <vector>
00023 #include <algorithm>
00024 #include "Timestep.h"
00025 
00026 /* clear GL, do rotation and scaling, draw tetrahedrons */
00027 
00029 void OutputString(GLfloat x, GLfloat y, char *string)
00030 {
00031   int length;
00032 
00033   length = strlen(string);
00034   glRasterPos2f(x, y);
00035   for ( int i = 0; i < length; i++)
00036     glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
00037 }
00038 
00040 void OutputString3(GLfloat x, GLfloat y, GLfloat z, char *string)
00041 {
00042   int length;
00043 
00044   length = strlen(string);
00045   glRasterPos3f(x, y, z);
00046   for ( int i = 0; i < length; i++)
00047     glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
00048 }
00049 
00051 
00059 void Timestep::draw_polygons(GLdouble ScreenWidth, GLdouble ScreenHeight,unsigned int colormap,GLdouble aspect_ratio,GLdouble scale,GLdouble xtri,GLdouble ytri,GLdouble ztri,GLdouble xtran,GLdouble ytran,GLdouble ztran,unsigned int fillpoly, bool showlabel, bool showlength, bool wire, bool pointmode, int chunk)
00060 {
00061 
00062 
00063   glNewList(step, GL_COMPILE);
00064   glPushMatrix();
00065   /*  bool Texture_On=0;
00066   bool Alpha_Add=0;
00067   bool Blend_On=0;
00068   bool Filtering_On=0;
00069   */
00070   glEnable(GL_DEPTH_TEST);
00071   glEnable(GL_LINE_SMOOTH);
00072   glShadeModel(GL_SMOOTH);
00073   /*
00074   if (Texture_On)
00075     glEnable(GL_TEXTURE_2D);
00076   else
00077     glDisable(GL_TEXTURE_2D);
00078 
00079 
00080   if (Alpha_Add)
00081     glBlendFunc(GL_SRC_ALPHA,GL_ONE); 
00082   else
00083     glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00084 
00085   // If we're blending, we don't want z-buffering.
00086   if (Blend_On)
00087     glDisable(GL_DEPTH_TEST); 
00088   else
00089     glEnable(GL_DEPTH_TEST); 
00090 
00091   if (Filtering_On) {
00092     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
00093                     GL_LINEAR_MIPMAP_LINEAR);
00094     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00095   } else {
00096     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
00097                     GL_NEAREST_MIPMAP_NEAREST);
00098     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
00099   }
00100   */
00101   glMatrixMode(GL_PROJECTION);
00102   glLoadIdentity();
00103   glClearColor(0.0, 0.0, 0.0, 0.0);
00104   glLineWidth(2.0);
00105   gluPerspective(100.0*scale, aspect_ratio, 1.0, 100.0);
00106   /*  glFrustum(-radius*scale, radius*scale,
00107     -radius*scale, radius*scale,
00108     -radius*2.0, radius*scale*10.0);*/
00109   glMatrixMode(GL_MODELVIEW);
00110   gluLookAt (0.0, 0.0, radius*2.0,
00111              0.0,0.0,0.0,
00112              0.0, 1.0, 0.0);
00113   glMatrixMode(GL_MODELVIEW);
00114   glPolygonMode(GL_FRONT_AND_BACK, fillpoly);
00115   glRotated(xtri, 1.0, 0.0, 0.0);
00116   glRotated(ytri, 0.0, 1.0, 0.0);
00117   glRotated(ztri, 0.0, 0.0, 1.0);
00118   glTranslated(xtran, ytran,ztran);
00119   glPointSize(2.0);
00120   display(colormap,wire,pointmode,fillpoly,chunk);
00121   if (showlabel)
00122     showlabels();
00123   if (showlength)
00124     showlengths();
00125   /*  glLoadIdentity();
00126       glMatrixMode(GL_PROJECTION);
00127       glPushMatrix();
00128       glLoadIdentity();
00129       glOrtho(0,ScreenWidth,0,ScreenHeight,-1.0,1.0);
00130       glDisable(GL_TEXTURE_2D);
00131       glDisable(GL_LIGHTING);
00132       // We don't want depth-testing either.
00133       glDisable(GL_DEPTH_TEST); 
00134       glColor4f(1.0,1.0,1.0,1.0);
00135       char statstring[80];
00136       snprintf(statstring,80,"Timestep: %u",step);
00137       OutputString(1,1,statstring);
00138       glPopMatrix();
00139   */
00140   glPopMatrix();
00141   glEndList();
00142   glCallList(step);
00143 }
00144 
00146 
00176 bool Timestep::loadfile(const char *filename, GLfloat * tetcolor, unsigned int timestep,unsigned int chunk)
00177 {
00178   FILE *infile;
00179   vector < Coordinate > coordinates;
00180   vector < unsigned int >vertices;
00181   char foo[20];
00182   unsigned int onevertex;
00183   infile = fopen(filename, "r");
00184   if (infile == NULL) {
00185     fprintf(stderr, "cannot open %s \n", filename);
00186     return (0);
00187   }
00188   GLdouble x, y, z;
00189   GLfloat r, g, b;
00190   step=timestep;
00191   while (fscanf(infile, "%lf%lf%lf%f%f%f", &x, &y, &z, &r, &g, &b)>0
00192          && !feof(infile))
00193     coordinates.push_back(Coordinate(chunk, x, y, z, r, g, b));
00194   // add any new coordinates to points
00195   // this could be more efficient, but we only do it once per file
00196   // so optimization is not a priority.
00197   for (unsigned int i = 0; i < coordinates.size(); i++) {
00198     vector < Coordinate >::iterator coorditer =
00199       find(points.begin(), points.end(), coordinates[i]);
00200     if (coorditer == points.end())
00201       points.push_back(coordinates[i]);
00202   }
00203   fscanf(infile, "%s\n", foo);
00204   if (strlen(foo)) {
00205     while (!feof(infile) && fscanf(infile, "%u", &onevertex)>0) {
00206       vertices.push_back(onevertex);
00207     }
00208     if(vertices.size()>0)
00209       {
00210         unsigned int chunkoffset=vertexarray.size();
00211         // now that we have the points and the faces add them to the drawarrays
00212         for (unsigned int vertex = 0; vertex < vertices.size(); vertex++) {
00213           if (vertices[vertex] > coordinates.size()) {
00214             fprintf(stderr,
00215                     "file format error vertex %d at %d line %d row %d is an undefined point beyond %d\n",
00216                     vertices[vertex], vertex, vertex / 12, vertex % 12,
00217                     coordinates.size());
00218             return (false);
00219           }
00220           Coordinate thiscoord = coordinates[vertices[vertex]];
00221           // put every face in the drawarray
00222           vertexarray.push_back(thiscoord.get_x());
00223           vertexarray.push_back(thiscoord.get_y());
00224           vertexarray.push_back(thiscoord.get_z());
00225           // put every point color in the pointcolor array
00226           pointcolor.push_back(thiscoord.get_r());
00227           pointcolor.push_back(thiscoord.get_g());
00228           pointcolor.push_back(thiscoord.get_b());
00229           // set the chunk color to the tetcolor parameter
00230           chunkcolor.push_back(tetcolor[0]);
00231           chunkcolor.push_back(tetcolor[1]);
00232           chunkcolor.push_back(tetcolor[2]);
00233           // put the line color in for the point
00234           linecolor.push_back(0.8);
00235           linecolor.push_back(0.8);
00236           linecolor.push_back(0.8);
00237         }
00238         unsigned int chunkend=vertexarray.size();
00239         pair <unsigned int,unsigned int> chunkoffpair;
00240         chunkoffpair.first= chunkoffset;
00241         chunkoffpair.second= chunkend-chunkoffset;
00242         chunkmap[chunk]=chunkoffpair;
00243         // each face has 3 edges which need midpoints and lengths
00244         for (unsigned int vertex = 0; vertex < vertices.size(); vertex += 3) {
00245           Coordinate c1 = coordinates[vertices[vertex]];
00246           Coordinate c2 = coordinates[vertices[vertex + 1]];
00247           Coordinate c3 = coordinates[vertices[vertex + 2]];
00248           Midpoint mid1_2(c1.get_x(), c2.get_x(), c1.get_y(), c2.get_y(),
00249                           c1.get_z(), c2.get_z());
00250           Midpoint mid2_3(c2.get_x(), c3.get_x(), c2.get_y(), c3.get_y(),
00251                           c2.get_z(), c3.get_z());
00252           Midpoint mid3_1(c3.get_x(), c1.get_x(), c3.get_y(), c1.get_y(),
00253                           c3.get_z(), c1.get_z());
00254           // now add any newly found midpoints
00255           vector < Midpoint >::iterator miter =
00256             find(midpoints.begin(), midpoints.end(), mid1_2);
00257           if (miter == midpoints.end())
00258             midpoints.push_back(mid1_2);
00259           miter = find(midpoints.begin(), midpoints.end(), mid2_3);
00260           if (miter == midpoints.end())
00261             midpoints.push_back(mid2_3);
00262           miter = find(midpoints.begin(), midpoints.end(), mid3_1);
00263           if (miter == midpoints.end())
00264             midpoints.push_back(mid3_1);
00265         }
00266       }
00267   }
00268   else {
00269     return (false);
00270   }
00271   return true;
00272 }
00273 
00275 
00283 void Timestep::calc_and_move()
00284 {
00285   double xmin,ymin,zmin;
00286   double xmax,ymax,zmax;
00287   double xwidth,ywidth,zwidth;
00288   double xcenter,ycenter,zcenter;
00289   xmin=ymin=zmin=10000000.0;
00290   xmax=ymax=zmax=-10000000.0;
00291   for(unsigned int i=0;i<points.size();i++)
00292     {
00293       if(xmin>points[i].get_x())
00294         xmin= points[i].get_x();
00295       if(ymin>points[i].get_y())
00296         ymin= points[i].get_y();
00297       if(zmin>points[i].get_z())
00298         zmin= points[i].get_z();
00299       if(xmax<points[i].get_x())
00300         xmax= points[i].get_x();
00301       if(ymax<points[i].get_y())
00302         ymax= points[i].get_y();
00303       if(zmax<points[i].get_z())
00304         zmax= points[i].get_z();
00305     }
00306   xcenter=(xmax+xmin)/2;
00307   ycenter=(ymax+ymin)/2;
00308   zcenter=(zmax+zmin)/2;
00309   xwidth=xmax-xmin;
00310   ywidth=ymax-ymin;
00311   zwidth=zmax-zmin;
00312   radius=max(zwidth,max(xwidth,ywidth));
00313   // now move them
00314   for(unsigned int i=0;i<vertexarray.size()-2;i+=3)
00315     {
00316       vertexarray[i]-=xmin+xcenter;
00317       vertexarray[i+1]-=ymin+ycenter;
00318       vertexarray[i+2]-=zmin+zcenter;
00319     }
00320   for(unsigned int i=0;i<points.size();i++)
00321     {
00322       Coordinate m=points[i];
00323       // leave the original label
00324       points[i].unsafe_set(m.get_x()-xmin-xcenter,m.get_y()-ymin-ycenter,m.get_z()-zmin-zcenter);
00325     }
00326   for(unsigned int i=0;i<midpoints.size();i++)
00327     {
00328       Midpoint m=midpoints[i];
00329       midpoints[i].set_mx(m.get_mx()-xmin-xcenter);
00330       midpoints[i].set_my(m.get_my()-ymin-ycenter);
00331       midpoints[i].set_mz(m.get_mz()-zmin-zcenter);
00332     }
00333 }
00334 
00335 
00337 
00343 void Timestep::display(unsigned int cmap,bool wire,bool pointmode, unsigned int fillpoly, int chunk)
00344 {
00345 // draw it
00346 // label a vertex
00347 // label an edge at the midpoint
00348   // draw a colored polygon
00349   // draw a wire polygon over it
00350   glEnableClientState(GL_VERTEX_ARRAY);
00351   glEnableClientState(GL_COLOR_ARRAY);
00352   // cache the current mode
00353   if(pointmode)
00354     glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
00355   else 
00356     glPolygonMode(GL_FRONT_AND_BACK, fillpoly);
00357   switch (cmap) {
00358   case 0:
00359     glColorPointer(3, GL_FLOAT, 0, &randomcolor[0]);
00360     break;
00361   case 1:
00362     glColorPointer(3, GL_FLOAT, 0, &chunkcolor[0]);
00363     break;
00364   case 2:
00365   default:
00366     glColorPointer(3, GL_FLOAT, 0, &pointcolor[0]);
00367     break;
00368   }
00369   if(chunk>=0)
00370     {
00371       // find the offsets for the chunk
00372       map <unsigned int, chunk_delim>::iterator chunkoff=chunkmap.find((unsigned int) chunk);
00373       if(chunkoff!=chunkmap.end())
00374         {
00375           glVertexPointer(3, GL_DOUBLE, 0, &vertexarray[chunkoff->second.first]);
00376           switch (cmap) {
00377           case 0:
00378             glColorPointer(3, GL_FLOAT, 0, &randomcolor[chunkoff->second.first]);
00379             break;
00380           case 1:
00381             glColorPointer(3, GL_FLOAT, 0, &chunkcolor[chunkoff->second.first]);
00382             break;
00383           case 2:
00384           default:
00385             glColorPointer(3, GL_FLOAT, 0, &pointcolor[chunkoff->second.first]);
00386             break;
00387           }
00388           glDrawArrays(GL_TRIANGLES, 0, chunkoff->second.second / 3);
00389         }
00390       else
00391         {
00392           glVertexPointer(3, GL_DOUBLE, 0, &vertexarray[0]);
00393           glDrawArrays(GL_TRIANGLES, 0, vertexarray.size() / 3);
00394         }
00395     }
00396   else
00397     {
00398       glVertexPointer(3, GL_DOUBLE, 0, &vertexarray[0]);
00399       glDrawArrays(GL_TRIANGLES, 0, vertexarray.size() / 3);
00400     }
00401   if(wire && !pointmode)
00402     {
00403       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00404       glVertexPointer(3, GL_DOUBLE, 0, &vertexarray[0]);
00405       glColorPointer(3, GL_FLOAT, 0, &linecolor[0]);
00406       glDrawArrays(GL_TRIANGLES, 0, vertexarray.size() / 3);
00407     }
00408 }
00409 
00410 
00412 
00416 void Timestep::showlengths()
00417 {
00418   glColor3f(1.0, 1.0, 1.0);
00419   for (unsigned int i = 0; i < midpoints.size(); i++) {
00420     OutputString3(midpoints[i].get_mx(), midpoints[i].get_my(),
00421                   midpoints[i].get_mz(), midpoints[i].get_length());
00422   }
00423 }
00424 
00426 
00429 void Timestep::showlabels()
00430 {
00431   glColor3f(1.0, 1.0, 1.0);
00432   for (unsigned int i = 0; i < points.size(); i++) {
00433     OutputString3(points[i].get_x(), points[i].get_y(),
00434                   points[i].get_z(), points[i].get_label());
00435 
00436   }
00437 }
00438 
00439 
00440 void Timestep::set_random_color(vector <Coordinate> randompoints)
00441 {
00442   //
00443   for(unsigned int i=0;i<vertexarray.size()-2;i+=3)
00444     {
00445       Coordinate finder(0,vertexarray[i],vertexarray[i+1],vertexarray[i+2],0.,0.,0.);
00446       //theoretically equal_range is more efficient.
00447       // but in practice it fails to find existing points
00448       // so its faster, but error prone.  which is unacceptable
00449       // so when it fails, we use find
00450       CoordIterPair p= equal_range(randompoints.begin(),randompoints.end(),finder);
00451       if(p.first !=p.second)
00452         {// we got it
00453           randomcolor.push_back(p.first->get_r());
00454           randomcolor.push_back(p.first->get_g());
00455           randomcolor.push_back(p.first->get_b());
00456 
00457         }
00458       else
00459         {
00460           vector <Coordinate>::iterator usefind= find(randompoints.begin(),randompoints.end(),finder);
00461           if(usefind !=randompoints.end())
00462             {
00463               randomcolor.push_back(usefind->get_r());
00464               randomcolor.push_back(usefind->get_g());
00465               randomcolor.push_back(usefind->get_b());
00466             }
00467           else
00468             {
00469               fprintf(stderr,"ERROR point not found \n");
00470               finder.edump();
00471               fprintf(stderr,"first is \n");
00472               if(p.first!=randompoints.end())
00473                 p.first->edump();
00474               fprintf(stderr,"second is \n");
00475               if(p.second!=randompoints.end())
00476                 p.second->edump();
00477               fprintf(stderr,"in color vector \n");
00478               for_each(randompoints.begin(),randompoints.end(),mem_fun_ref(&Coordinate::edump));
00479             }
00480         }
00481     }
00482 }

Generated on Wed Oct 29 10:01:52 2003 for Tetraviewer by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002