00001
00002
00003
00004
00005
00006
00007
00008
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() );
00051 N.push_back( Vector() );
00052 T.push_back( Vector() );
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();
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())
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];
00091 int ni[10] = { -1, -1, -1, -1, };
00092 int ti[10] = { -1, -1, -1, -1, };
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