Main Page | File List

TriangleMesh.cpp

Go to the documentation of this file.
00001 /**
00002  *\file         TriangleMesh.cpp
00003  *
00004  *\brief        
00005  *
00006  *\author       Xianming Chen
00007  *
00008  *\date         11 Jul 2004
00009  */
00010 
00011 
00012 #include "TriangleMesh.h"
00013 #include <fstream>
00014 #include <iostream>
00015 #include <cassert>
00016 #include <string>
00017 #include <GL/gl.h>
00018 
00019 
00020 using namespace std;
00021 
00022 
00023 namespace columbia
00024 {
00025 
00026   static void skip_line(istream& is)
00027   {
00028     char next;
00029     while( is >> noskipws >> next && next != '\n' );
00030   }
00031   
00032   static bool skip_comment_line(istream& is, char comment_tag)
00033   {
00034     char next;
00035     while( is >> skipws >> next ) 
00036     {
00037       is.putback(next);
00038       if(next == comment_tag) skip_line(is);
00039       else
00040         return true;
00041     }
00042     return false;
00043   }
00044 
00045 
00046   TriangleMesh :: TriangleMesh(const char* obj_fname) : has_normal(false), has_texture(false), texImage(0)
00047   {
00048     ifstream is(obj_fname);
00049 
00050     if(is)
00051     {
00052       bool no_normal = true;
00053       bool no_tex = true;
00054 
00055       while( skip_comment_line(is, '#') ) 
00056       {
00057         string ele_id;
00058         float x, y, z;    
00059 
00060         if( ! (is >> ele_id) ) break;
00061 
00062         if(ele_id == "v")
00063         {
00064           is >> x >> y >> z;
00065           V.push_back( Vertex(x, y, z) );
00066         }
00067         else if(ele_id == "vt")
00068         {
00069           no_tex = false;
00070           is >> x >> y >> z;
00071           is.clear();                           // is z(i.e. w) is not available, have to clear error flag.
00072           T.push_back( Vector(x, y, z) );
00073         }
00074         else if(ele_id == "vn")
00075         {
00076           no_normal = false;
00077           is >> x >> y >> z;
00078           if(! is.good())                      // in case it is -1#IND00
00079           {
00080             x = y = z = 0.0;
00081             is.clear();
00082             skip_line(is);
00083           }
00084           N.push_back( Vector(x, y, z) );
00085         }
00086         else if(ele_id == "f")
00087         {
00088           int vi[10];                               // vertex indices.
00089           int ni[10] = { -1, -1, -1, -1, };         // normal indices.
00090           int ti[10] = { -1, -1, -1, -1, };         // tex indices.
00091           int i = 0;
00092           for(char c; i<10; ++i)
00093           {
00094             if(no_tex && no_normal) is >> vi[i];
00095             else if(no_tex)         is >> vi[i] >> c >> c >> ni[i];
00096             else if(no_normal)      is >> vi[i] >> c >> ti[i];
00097             else                    is >> vi[i] >> c >> ti[i] >> c >>  ni[i];
00098 
00099             if( ! is.good() )       break;
00100           }
00101           for(int k=0; k<=i-3; k++)
00102           {
00103             F.push_back( TriangleFace(vi[0]-1, vi[k+1]-1, vi[k+2]-1, ti[0]-1, ti[k+1]-1, ti[k+2]-1, ni[0]-1, ni[k+1]-1, ni[k+2]-1) );
00104           }
00105           is.clear();
00106         }
00107         else 
00108           skip_line(is);
00109       }
00110       is.close();
00111       init();
00112     }
00113     else 
00114       cerr << "Can't open input file " << obj_fname << endl;
00115   }
00116 
00117   void TriangleMesh :: init()
00118   {
00119     has_normal = N.size();
00120     has_texture = T.size();
00121     total_triangles = F.size();
00122     cout << "total vertices " << V.size() << endl;
00123     cout << "total normals " << N.size() << endl;
00124     cout << "total texture coordinates " << T.size() << endl;
00125     cout << "total triangles " << F.size() << endl;
00126 
00127 
00128     bbox = BBox(*this);
00129     cout << "bounding box is " << bbox << endl;
00130   }
00131   
00132   void TriangleMesh :: initTexture()
00133   {
00134     if(has_texture && texImage)
00135     {
00136       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00137 
00138       glGenTextures(1, &texName);
00139       glBindTexture(GL_TEXTURE_2D, texName);
00140 
00141       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00142       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00143       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00144       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00145 
00146       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texImage->hReso, texImage->vReso, 
00147                    0, GL_RGB, GL_FLOAT, texImage->data);
00148     }
00149   }
00150 
00151 
00152   void TriangleMesh :: glDraw() const
00153   {
00154     if(has_normal) 
00155     {
00156       glEnable(GL_LIGHTING);
00157       glEnable(GL_LIGHT0);
00158     }
00159     else
00160       glDisable(GL_LIGHTING);
00161     
00162     if(has_texture && texImage)
00163     {
00164       glEnable(GL_TEXTURE_2D);
00165       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, has_normal? GL_MODULATE : GL_DECAL);
00166       glBindTexture(GL_TEXTURE_2D, texName);
00167       glEnable(GL_TEXTURE_2D);
00168 
00169       if(has_normal) 
00170       {
00171         glBegin(GL_TRIANGLES);
00172         {
00173           for(int f = 0; f < total_triangles; ++f)
00174           {
00175             int i = F[f].i, j = F[f].j, k = F[f].k;
00176             int ni = F[f].ni, nj = F[f].nj, nk = F[f].nk;
00177             int ti = F[f].ti, tj = F[f].tj, tk = F[f].tk;
00178 
00179             glTexCoord2f(T[ti].x, T[ti].y); glNormal3f( N[ni].x, N[ni].y, N[ni].z ); glVertex3f( V[i].x, V[i].y, V[i].z );
00180             glTexCoord2f(T[tj].x, T[tj].y); glNormal3f( N[nj].x, N[nj].y, N[nj].z ); glVertex3f( V[j].x, V[j].y, V[j].z );
00181             glTexCoord2f(T[tk].x, T[tk].y); glNormal3f( N[nk].x, N[nk].y, N[nk].z ); glVertex3f( V[k].x, V[k].y, V[k].z );
00182           }
00183         }
00184         glEnd();
00185       }
00186       else
00187       {
00188         glBegin(GL_TRIANGLES);
00189         {
00190           for(int f = 0; f < total_triangles; ++f)
00191           {
00192             int i = F[f].i, j = F[f].j, k = F[f].k;
00193             int ti = F[f].ti, tj = F[f].tj, tk = F[f].tk;
00194 
00195             glTexCoord2f(T[ti].x, T[ti].y); glVertex3f( V[i].x, V[i].y, V[i].z );
00196             glTexCoord2f(T[tj].x, T[tj].y); glVertex3f( V[j].x, V[j].y, V[j].z );
00197             glTexCoord2f(T[tk].x, T[tk].y); glVertex3f( V[k].x, V[k].y, V[k].z );
00198           }
00199         }
00200         glEnd();
00201       }
00202       glDisable(GL_TEXTURE_2D);
00203     }
00204     else
00205     {
00206       if(has_normal) 
00207       {
00208         glBegin(GL_TRIANGLES);
00209         {
00210           for(int f = 0; f < total_triangles; ++f)
00211           {
00212             int i = F[f].i, j = F[f].j, k = F[f].k;
00213             int ni = F[f].ni, nj = F[f].nj, nk = F[f].nk;
00214 
00215             glNormal3f( N[ni].x, N[ni].y, N[ni].z ); glVertex3f( V[i].x, V[i].y, V[i].z );
00216             glNormal3f( N[nj].x, N[nj].y, N[nj].z ); glVertex3f( V[j].x, V[j].y, V[j].z );
00217             glNormal3f( N[nk].x, N[nk].y, N[nk].z ); glVertex3f( V[k].x, V[k].y, V[k].z );
00218           }
00219         }
00220         glEnd();
00221       }
00222       else
00223       {
00224         glBegin(GL_TRIANGLES);
00225         {
00226           for(int f = 0; f < total_triangles; ++f)
00227           {
00228             int i = F[f].i, j = F[f].j, k = F[f].k;
00229 
00230             glVertex3f( V[i].x, V[i].y, V[i].z );
00231             glVertex3f( V[j].x, V[j].y, V[j].z );
00232             glVertex3f( V[k].x, V[k].y, V[k].z );
00233           }
00234         }
00235         glEnd();
00236       }
00237     }
00238   }
00239   
00240 
00241 
00242 };
00243 
00244 
00245 
00246 

Generated on Sun Jul 18 20:32:35 2004 by doxygen 1.3.6