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

Generated on Mon Jul 19 17:20:27 2004 by doxygen 1.3.6