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 using namespace std;
00019 
00020 
00021 namespace columbia
00022 {
00023 
00024   static void skip_line(istream& is)
00025   {
00026     char next;
00027     while( is >> noskipws >> next && next != '\n' );
00028   }
00029   
00030   static bool skip_comment_line(istream& is, char comment_tag)
00031   {
00032     char next;
00033     while( is >> skipws >> next ) 
00034     {
00035       is.putback(next);
00036       if(next == comment_tag) skip_line(is);
00037       else
00038         return true;
00039     }
00040     return false;
00041   }
00042 
00043 
00044   TriangleMesh :: TriangleMesh(const char* obj_fname) : has_normal(false)
00045   {
00046     ifstream is(obj_fname);
00047 
00048     if(is)
00049     {
00050       V.push_back( Vertex() );                           // the 0'th vertex is ignored.
00051       N.push_back( Vector() );                           // the 0'th normal is ignored.
00052       T.push_back( Vector() );                           // the 0'th texture is ignored.
00053 
00054       bool no_normal = true;
00055       bool no_tex = true;
00056 
00057       while( skip_comment_line(is, '#') ) 
00058       {
00059         string ele_id;
00060         float x, y, z;    
00061 
00062         if( ! (is >> ele_id) ) break;
00063 
00064         if(ele_id == "v")
00065         {
00066           is >> x >> y >> z;
00067           V.push_back( Vertex(x, y, z) );
00068         }
00069         else if(ele_id == "vt")
00070         {
00071           no_tex = false;
00072           is >> x >> y >> z;
00073           is.clear();                           // is z(i.e. w) is not available, have to clear error flag.
00074           T.push_back( Vector(x, y, z) );
00075         }
00076         else if(ele_id == "vn")
00077         {
00078           no_normal = false;
00079           is >> x >> y >> z;
00080           if(! is.good())                      // in case it is -1#IND00
00081           {
00082             x = y = z = 0.0;
00083             is.clear();
00084             skip_line(is);
00085           }
00086           N.push_back( Vector(x, y, z) );
00087         }
00088         else if(ele_id == "f")
00089         {
00090           int vi[10];                               // vertex indices.
00091           int ni[10] = { -1, -1, -1, -1, };         // normal indices.
00092           int ti[10] = { -1, -1, -1, -1, };         // tex indices.
00093           int i = 0;
00094           for(char c; i<10; ++i)
00095           {
00096             if(no_tex && no_normal) is >> vi[i];
00097             else if(no_tex)         is >> vi[i] >> c >> c >> ni[i];
00098             else if(no_normal)      is >> vi[i] >> c >> ti[i];
00099             else                    is >> vi[i] >> c >> ti[i] >> c >>  ni[i];
00100 
00101             if( ! is.good() )       break;
00102           }
00103           for(int k=0; k<=i-3; k++)
00104           {
00105             F.push_back( TriangleFace(vi[0], vi[k+1], vi[k+2], ti[0], ti[k+1], ti[k+2], ni[0], ni[k+1], ni[k+2]) );
00106           }
00107           is.clear();
00108         }
00109         else 
00110           skip_line(is);
00111       }
00112 
00113       has_normal = (N.size() > 1);
00114       total_triangles = F.size();
00115       is.close();
00116       cout << "total vertices " << V.size() - 1 << endl;
00117       cout << "total normals " << N.size() - 1 << endl;
00118       cout << "total triangles " << F.size() << endl;
00119     }
00120     else 
00121       cerr << "Can't open input file " << obj_fname << endl;
00122 
00123     bbox = BBox(*this);
00124     cout << "bounding box is " << bbox << endl;
00125   }
00126 
00127   void TriangleMesh :: TriangulateSphere(int depth)
00128   {
00129     const float X = .525731112119133606;
00130     const float Z = .850650808352039932;
00131     float vdata[12][3] = {    
00132       {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},    
00133       {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},    
00134       {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} 
00135     };
00136     int tindices[20][3] = { 
00137       {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
00138       {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
00139       {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
00140       {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
00141 
00142     V.push_back(Vertex());
00143     for(int i=0; i<12; i++)
00144     {
00145       V.push_back( Vertex(vdata[i][0], vdata[i][1], vdata[i][2]) );
00146     }
00147   
00148     for(int i=0; i<20; i++)
00149     {
00150       F.push_back( TriangleFace(tindices[i][0]+1, tindices[i][1]+1, tindices[i][2]+1,  tindices[i][0]+1, tindices[i][1]+1, tindices[i][2]+1) );
00151     }
00152     for(int d=1; d<depth; d++)  
00153     {
00154       int faces = F.size();
00155       for(int f=0; f < faces; ++f)
00156       {
00157         int i = F[0].i, j = F[0].j, k = F[0].k;
00158         
00159         Vertex v1 = V[i];
00160         Vertex v2 = V[j];
00161         Vertex v3 = V[k];
00162 
00163         Vertex v12 = ((v1 + v2) / 2).GetUnit();
00164         Vertex v13 = ((v1 + v3) / 2).GetUnit();
00165         Vertex v23 = ((v3 + v2) / 2).GetUnit();
00166 
00167         int ij = V.size();
00168         V.push_back(v12);
00169         
00170         int ik = V.size();
00171         V.push_back(v13);
00172         
00173         int jk = V.size();
00174         V.push_back(v23);
00175         
00176         F.erase( F.begin() );
00177         
00178         F.push_back( TriangleFace(i, ik, ij, i, ik, ij) );
00179         F.push_back( TriangleFace(j, jk, ij, j, jk, ij) );
00180         F.push_back( TriangleFace(k, ik, jk, k, ik, jk) );
00181         F.push_back( TriangleFace(jk, ik,ij, jk, ik,ij) );
00182       }
00183     }
00184     N = V;
00185     
00186     has_normal = (N.size() > 1);
00187     total_triangles = F.size();
00188     bbox = BBox(*this);
00189     cout << (*this) << endl;
00190   }
00191   
00192 
00193 
00194 };
00195 
00196 
00197 
00198 

Generated on Wed Jul 14 19:41:55 2004 by doxygen 1.3.6