Advertisement
pushrbx

Untitled

Apr 25th, 2013
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.46 KB | None | 0 0
  1. void CObjMeshParser::parse(shared_ptr<CMesh>& pMesh, const string& strFileName)
  2. {
  3.     //  usefull to retrieve material files
  4.     {
  5.         const path filePath(strFileName);
  6.         m_branchPath = filePath.branch_path();
  7.     }
  8.  
  9.     ifstream ifs(strFileName.c_str(), ios::in|ios::ate);
  10.     if (!ifs)
  11.         throw(CFileNotFoundException(strFileName));
  12.  
  13.     const int fileSize = ifs.tellg();    //  get the file size (we started at the end)...
  14.     ifs.seekg (0, ios::beg);  //  ...then get back to start
  15.    
  16.     if (0 == fileSize)
  17.         throw CEmptyFileException();
  18.  
  19.     //  explain what's going on
  20.     CLogger::get() << "Parsing file \"" << strFileName << "\" (file size = " << fileSize << " bytes)...\n" << flush;
  21.    
  22.     // do a bit of cleaning before adding data in case the mesh was used before.
  23.     pMesh->clear();
  24.  
  25.     // and go.
  26.     int percent = 10;   //  progress indicator
  27.     while(skipCommentLine(ifs))
  28.     {
  29.         // show progress for files larger than one Mo
  30.         if ((fileSize > 1024*1024) && (100*ifs.tellg()/fileSize >= percent)) {
  31.             percent = 100*ifs.tellg()/fileSize;
  32.             percent = (percent/10)*10;
  33.             CLogger::get() << "  " << percent << " % done...\n" << flush;
  34.             percent += 10;
  35.         }
  36.            
  37.         if (false == processLine(pMesh, ifs))
  38.             break;
  39.     }
  40. }
  41.  
  42. bool CObjMeshParser::skipCommentLine(istream& is)
  43. {
  44.     char next;
  45.     while( is >> std::skipws >> next )
  46.     {
  47.         is.putback(next);
  48.         if ('#' == next)
  49.             skipLine(is);
  50.         else
  51.             return true;
  52.     }
  53.     return false;
  54. }
  55.  
  56. bool CObjMeshParser::processLine(shared_ptr<CMesh>& pMesh, istream& is)
  57. {
  58.     string ele_id;
  59.     float x, y, z;
  60.    
  61.     if (!(is >> ele_id))
  62.         return false;
  63.    
  64.     if ("mtllib" == ele_id) {
  65.         string strFileName;
  66.         is >> strFileName;
  67.         parseMtlLib(strFileName);
  68.     }
  69.     else if ("usemtl" == ele_id) {
  70.         string strMtlName;
  71.         is >> strMtlName;
  72.         map<string, SMaterial>::iterator it = m_materialMap.find(strMtlName);
  73.         if (it != m_materialMap.end())
  74.             pMesh->setMaterial((*it).second);
  75.         else
  76.             CLogger::get() << "  * Material not found in current mtllib :\"" << strMtlName << "\". Ignoring material.\n";
  77.     }
  78.     else if ("v" == ele_id) {   //  vertex data
  79.         is >> x >> y >> z;
  80.         pMesh->addVertex(SVertex(x, y, z));
  81.     }
  82.     else if ("vt" == ele_id) {  // texture data
  83.         is >> x >> y >> z;
  84.         is.clear();                           // is z (i.e. w) is not available, have to clear error flag.
  85.         pMesh->addTextureCoord(SVertex(x, y, z));
  86.     }
  87.     else if ("vn" == ele_id) {  // normal data
  88.         is >> x >> y >> z;
  89.         if(!is.good()) {                     // in case it is -1#IND00
  90.             x = y = z = 0.0;
  91.             is.clear();
  92.             skipLine(is);
  93.         }
  94.         pMesh->addNormal(SVertex(x, y, z));
  95.     }
  96.     else if ("f" == ele_id) {   //  face data
  97.                                 //  face treatment
  98.                                 //  Note: obviously this technique only works for convex polygons with ten verts or less.
  99.         int vi[10];                               // vertex indices.
  100.         int ni[10] = { -1, -1, -1, -1, };         // normal indices.
  101.         int ti[10] = { -1, -1, -1, -1, };         // tex indices.
  102.         int i = 0;
  103.         for (char c; i<10; ++i) {
  104.             if(!pMesh->hasTextureCoords() && !pMesh->hasNormals())
  105.                 is >> vi[i];
  106.             else if(!pMesh->hasTextureCoords())
  107.                 is >> vi[i] >> c >> c >> ni[i];
  108.             else if(!pMesh->hasNormals())
  109.                 is >> vi[i] >> c >> ti[i];
  110.             else
  111.                 is >> vi[i] >> c >> ti[i] >> c >>  ni[i];
  112.            
  113.             if(!is.good())
  114.                 break;
  115.         }
  116.         //  Create the polygon face
  117.         SPolygonFace face;
  118.         for (int k=0; k < i; ++k)
  119.             face.addVertTexNorm(vi[k], ti[k], ni[k]);
  120.         pMesh->addFace(face);
  121.        
  122.         is.clear();
  123.     }
  124.     else
  125.         skipLine(is);
  126.     return true;
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement