Files Classes Functions Hierarchy
00001 #include <sstream> 00002 using namespace std; 00003 00004 #include <print.h> 00005 #include <message.h> 00006 00007 #include <vrmlshapeparse.h> 00008 00009 00010 // DEBUGGING THE PARSER 00011 // Turn on or off the debugging the parser. 00012 // By comparing the output debug.txt with the vrml file 00013 // the parsers state can be observed by seeing which 00014 // tokens it was trying to compare. So the parsers state 00015 // is easily observed. 00016 #define DEBUG_VRMLSHAPEPARSE 00017 00018 #ifdef DEBUG_VRMLSHAPEPARSE 00019 // This is very convenient, but be aware that it does 00020 // introduce a global symbol into the *.o space 00021 // at the linking stage. 00022 messagefile dbg("debug.txt",true); 00023 #define DEBUG_VRML(x) cout << #x << endl 00024 #else 00025 #define DEBUG_VRML(x) 00026 #endif 00027 00028 #ifdef DEBUG_VRMLSHAPEPARSE 00029 00030 #endif 00031 00032 00033 void vrmlshapetoken::depth( vrmlshapeparse & p ) const 00034 { 00035 ++p.tokenstream; 00036 } 00037 00038 void vrmlshapetoken::consumescope 00039 ( 00040 vrmlshapeparse & p, 00041 stringc & left, 00042 stringc & right 00043 ) const 00044 { 00045 ++p.tokenstream; 00046 // Insist that client knows what they are 00047 // doing and is expecting the scope. 00048 assert(p.tokenstream()==left); 00049 00050 int count = 1; 00051 00052 ++p.tokenstream; 00053 while ((count>0) && !p.tokenstream) 00054 { 00055 stringc & s(p.tokenstream()); 00056 if (s==left) 00057 { 00058 ++count; 00059 ++p.tokenstream; 00060 } 00061 else 00062 { 00063 if (s==right) 00064 { 00065 --count; 00066 ++p.tokenstream; 00067 } 00068 else 00069 depth(p); 00070 }; 00071 } 00072 } 00073 00074 00075 void vrmlshapetoken::eval 00076 ( 00077 bool & handled, 00078 vrmlshapeparse & p 00079 ) const 00080 { 00081 assert(!p.tokenstream); 00082 00083 #ifdef DEBUG_VRMLSHAPEPARSE 00084 //messagefile("debug.txt")() << p.tokenstream() << "==" << id << endl; 00085 dbg() << p.tokenstream() << "==" << id << endl; 00086 #endif 00087 00088 if (p.tokenstream()==id) 00089 { 00090 handled = true; 00091 this->eval(p); 00092 } 00093 else 00094 handled = false; 00095 } 00096 00097 void vrmlshapetokengroup::eval( vrmlshapeparse & p ) const 00098 { 00099 uint kmax = tokens.size(); 00100 uint k=0; 00101 bool res(false); 00102 for ( ; k<kmax; ++k) 00103 { 00104 00105 tokens[k]->eval(res,p); 00106 if (res) 00107 return; 00108 } 00109 00110 if (res==false) 00111 ++p.tokenstream; 00112 00113 /* 00114 00115 vector< vrmlshapetoken* >::const_iterator k = tokens.begin(); 00116 vector< vrmlshapetoken* >::const_iterator kend = tokens.end(); 00117 00118 bool res = false; 00119 // cout << "> " << p.tokenstream() << endl; 00120 while ((k!=kend) && (res==false)) 00121 { 00122 (*k)->eval(res,p); 00123 ++k; 00124 } 00125 // If the token was not consumed/processed, consume it. 00126 if (res==false) 00127 ++p.tokenstream; 00128 */ 00129 } 00130 00131 vrmlshapetokengroup::~vrmlshapetokengroup() 00132 { 00133 if( tokens.empty()==false) 00134 { 00135 for (uint i=0; i<tokens.size(); ++i) 00136 { 00137 delete tokens[i]; 00138 tokens[i]=0; 00139 } 00140 } 00141 } 00142 00143 00144 00145 boolc vrmlshapeparse::readfile 00146 ( 00147 stringc & filename 00148 ) 00149 { 00150 //if (!tokenstream.readfile(filename.c_str())) 00151 // return false; 00152 string str; 00153 00154 if( !tokenizermisc::readfile(str,filename) ) 00155 return false; 00156 00157 #ifdef DEBUG_VRMLSHAPEPARSE 00158 dbg() << "File read" << endl; 00159 #endif 00160 00161 tokenstream.readaslines(str); 00162 00163 00164 tokenstream.stripcomment("#"); 00165 00166 tokenstream.subtract(","); 00167 tokenstream.atomize("{"); 00168 tokenstream.atomize("}"); 00169 tokenstream.atomize("["); 00170 tokenstream.atomize("]"); 00171 00172 tokenstream.remove_if(); 00173 00174 // This is not entirely correct. I am using 00175 // this to eliminate leading tabs... 00176 // But a general subtract functional object 00177 // would be best. Or replace bad characters with 00178 // a space then subtract. 00179 tokenstream.trim(); 00180 tokenstream.subtract(" "); 00181 00182 tg.tokens.push_back( new vrmlshapeShape() ); 00183 00184 // The iterator is responsible for incrementing the stream. 00185 for (tokenstream.reset(); !tokenstream; ) 00186 tg.eval(*this); 00187 00188 return true; 00189 } 00190 00191 vrmlshapeIndexedFaceSet::vrmlshapeIndexedFaceSet() 00192 : vrmlshapetoken("IndexedFaceSet") 00193 { 00194 tg.tokens.push_back(new vrmlshapepoint()); 00195 tg.tokens.push_back(new vrmlshapecoordIndex()); 00196 tg.tokens.push_back(new vrmlshapeNormal()); 00197 } 00198 00199 void vrmlshapeIndexedFaceSet::eval( vrmlshapeparse & p ) const 00200 { 00201 assert(p.vshp.empty()==false); 00202 p.vshp.back().istriangles = true; 00203 00204 consumescope(p,"{","}"); 00205 00206 #ifdef DEBUG_VRMLSHAPEPARSE 00207 dbg() << id << endl; 00208 #endif 00209 } 00210 00211 vrmlshapeMaterial::vrmlshapeMaterial() 00212 : vrmlshapetoken("Material") 00213 { 00214 tg.tokens.push_back(new vrmlshapediffuseColor()); 00215 tg.tokens.push_back(new vrmlshapeemissiveColor()); 00216 tg.tokens.push_back(new vrmlshapeambientIntensity()); 00217 } 00218 00219 void vrmlshapeMaterial::eval( vrmlshapeparse & p ) const 00220 { 00221 assert(p.vshp.empty()==false); 00222 00223 consumescope(p,"{","}"); 00224 00225 #ifdef DEBUG_VRMLSHAPEPARSE 00226 dbg() << id << endl; 00227 #endif 00228 } 00229 00230 00231 00232 void vrmlshapecoordIndex::eval( vrmlshapeparse & p ) const 00233 { 00234 assert(p.vshp.empty()==false); 00235 ++p.tokenstream; 00236 assert(p.tokenstream()=="["); 00237 ++p.tokenstream; 00238 int x; 00239 while((p.tokenstream()!="]") && !p.tokenstream) 00240 { 00241 stringstream s(p.tokenstream()); 00242 s >> x; 00243 p.vshp.back().coordIndex.push_back(x); 00244 00245 ++p.tokenstream; 00246 } 00247 ++p.tokenstream; 00248 00249 #ifdef DEBUG_VRMLSHAPEPARSE 00250 dbg() << id << endl; 00251 #endif 00252 } 00253 00254 00255 void vrmlshapeNormal::eval( vrmlshapeparse & p ) const 00256 { 00257 assert(p.vshp.empty()==false); 00258 ++p.tokenstream; 00259 assert(p.tokenstream()=="{"); 00260 ++p.tokenstream; 00261 assert(p.tokenstream()=="vector"); 00262 ++p.tokenstream; 00263 00264 assert(p.tokenstream()=="["); 00265 ++p.tokenstream; 00266 double d; 00267 while((p.tokenstream()!="]") && !p.tokenstream) 00268 { 00269 stringstream s(p.tokenstream()); 00270 s >> d; 00271 p.vshp.back().normal.push_back(d); 00272 00273 ++p.tokenstream; 00274 } 00275 ++p.tokenstream; 00276 00277 assert(p.tokenstream()=="}"); 00278 ++p.tokenstream; 00279 00280 assert((p.vshp.back().normal.size()%3)==0); 00281 00282 #ifdef DEBUG_VRMLSHAPEPARSE 00283 dbg() << id << endl; 00284 #endif 00285 } 00286 00287 00288 00289 void vrmlshapepoint::eval( vrmlshapeparse & p ) const 00290 { 00291 assert(p.vshp.empty()==false); 00292 ++p.tokenstream; 00293 assert(p.tokenstream()=="["); 00294 ++p.tokenstream; 00295 double d; 00296 while((p.tokenstream()!="]") && !p.tokenstream) 00297 { 00298 stringstream s(p.tokenstream()); 00299 s >> d; 00300 p.vshp.back().point.push_back(d); 00301 00302 ++p.tokenstream; 00303 } 00304 ++p.tokenstream; 00305 00306 assert((p.vshp.back().point.size()%3)==0); 00307 00308 #ifdef DEBUG_VRMLSHAPEPARSE 00309 dbg() << id << endl; 00310 #endif 00311 } 00312 00313 00314 00315 void vrmlshapediffuseColor::eval 00316 ( 00317 vrmlshapeparse & p 00318 ) const 00319 { 00320 assert(p.vshp.empty()==false); 00321 ++p.tokenstream; 00322 double x; 00323 stringstream(p.tokenstream()) >> x; 00324 p.vshp.back().diffuseColor[0] = x; 00325 ++p.tokenstream; 00326 stringstream(p.tokenstream()) >> x; 00327 p.vshp.back().diffuseColor[1] = x; 00328 ++p.tokenstream; 00329 stringstream(p.tokenstream()) >> x; 00330 p.vshp.back().diffuseColor[2] = x; 00331 ++p.tokenstream; 00332 00333 #ifdef DEBUG_VRMLSHAPEPARSE 00334 dbg() << id << endl; 00335 #endif 00336 } 00337 00338 void vrmlshapeemissiveColor::eval 00339 ( 00340 vrmlshapeparse & p 00341 ) const 00342 { 00343 assert(p.vshp.empty()==false); 00344 ++p.tokenstream; 00345 double x; 00346 uintc last(p.vshp.size()-1); 00347 stringstream(p.tokenstream()) >> x; 00348 p.vshp[last].emissiveColor[0] = x; 00349 ++p.tokenstream; 00350 stringstream(p.tokenstream()) >> x; 00351 p.vshp[last].emissiveColor[1] = x; 00352 ++p.tokenstream; 00353 stringstream(p.tokenstream()) >> x; 00354 p.vshp[last].emissiveColor[2] = x; 00355 ++p.tokenstream; 00356 00357 #ifdef DEBUG_VRMLSHAPEPARSE 00358 dbg() << id << endl; 00359 #endif 00360 } 00361 00362 00363 void vrmlshapeambientIntensity::eval 00364 ( 00365 vrmlshapeparse & p 00366 ) const 00367 { 00368 assert(p.vshp.empty()==false); 00369 ++p.tokenstream; 00370 double x; 00371 stringstream(p.tokenstream()) >> x; 00372 p.vshp.back().ambientIntensity = x; 00373 00374 ++p.tokenstream; 00375 00376 #ifdef DEBUG_VRMLSHAPEPARSE 00377 dbg() << id << endl; 00378 #endif 00379 } 00380 00381 vrmlshapeIndexedLineSet::vrmlshapeIndexedLineSet() 00382 : vrmlshapetoken("IndexedLineSet") 00383 { 00384 tg.tokens.push_back(new vrmlshapepoint()); 00385 tg.tokens.push_back(new vrmlshapecoordIndex()); 00386 } 00387 00388 void vrmlshapeIndexedLineSet::eval( vrmlshapeparse & p ) const 00389 { 00390 assert(p.vshp.empty()==false); 00391 p.vshp.back().isline = true; 00392 00393 consumescope(p,"{","}"); 00394 00395 #ifdef DEBUG_VRMLSHAPEPARSE 00396 dbg() << id << endl; 00397 #endif 00398 } 00399 00400 vrmlshapeShape::vrmlshapeShape() 00401 : vrmlshapetoken("Shape") 00402 { 00403 DEBUG_VRML(vrmlshapeShape::vrmlshapeShape()); 00404 00405 tg.tokens.push_back( new vrmlshapeIndexedLineSet() ); 00406 tg.tokens.push_back( new vrmlshapeIndexedFaceSet() ); 00407 tg.tokens.push_back( new vrmlshapeMaterial() ); 00408 } 00409 00410 void vrmlshapeShape::eval( vrmlshapeparse & p ) const 00411 { 00412 DEBUG_VRML(void vrmlshapeShape::eval( vrmlshapeparse & p ) const); 00413 00414 p.vshp.push_back( vrmlshaperaw() ); 00415 00416 consumescope(p,"{","}"); 00417 } 00418 00419 00420
1.5.8