Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void CObjMeshParser::parse(shared_ptr<CMesh>& pMesh, const string& strFileName)
- {
- // usefull to retrieve material files
- {
- const path filePath(strFileName);
- m_branchPath = filePath.branch_path();
- }
- ifstream ifs(strFileName.c_str(), ios::in|ios::ate);
- if (!ifs)
- throw(CFileNotFoundException(strFileName));
- const int fileSize = ifs.tellg(); // get the file size (we started at the end)...
- ifs.seekg (0, ios::beg); // ...then get back to start
- if (0 == fileSize)
- throw CEmptyFileException();
- // explain what's going on
- CLogger::get() << "Parsing file \"" << strFileName << "\" (file size = " << fileSize << " bytes)...\n" << flush;
- // do a bit of cleaning before adding data in case the mesh was used before.
- pMesh->clear();
- // and go.
- int percent = 10; // progress indicator
- while(skipCommentLine(ifs))
- {
- // show progress for files larger than one Mo
- if ((fileSize > 1024*1024) && (100*ifs.tellg()/fileSize >= percent)) {
- percent = 100*ifs.tellg()/fileSize;
- percent = (percent/10)*10;
- CLogger::get() << " " << percent << " % done...\n" << flush;
- percent += 10;
- }
- if (false == processLine(pMesh, ifs))
- break;
- }
- }
- bool CObjMeshParser::skipCommentLine(istream& is)
- {
- char next;
- while( is >> std::skipws >> next )
- {
- is.putback(next);
- if ('#' == next)
- skipLine(is);
- else
- return true;
- }
- return false;
- }
- bool CObjMeshParser::processLine(shared_ptr<CMesh>& pMesh, istream& is)
- {
- string ele_id;
- float x, y, z;
- if (!(is >> ele_id))
- return false;
- if ("mtllib" == ele_id) {
- string strFileName;
- is >> strFileName;
- parseMtlLib(strFileName);
- }
- else if ("usemtl" == ele_id) {
- string strMtlName;
- is >> strMtlName;
- map<string, SMaterial>::iterator it = m_materialMap.find(strMtlName);
- if (it != m_materialMap.end())
- pMesh->setMaterial((*it).second);
- else
- CLogger::get() << " * Material not found in current mtllib :\"" << strMtlName << "\". Ignoring material.\n";
- }
- else if ("v" == ele_id) { // vertex data
- is >> x >> y >> z;
- pMesh->addVertex(SVertex(x, y, z));
- }
- else if ("vt" == ele_id) { // texture data
- is >> x >> y >> z;
- is.clear(); // is z (i.e. w) is not available, have to clear error flag.
- pMesh->addTextureCoord(SVertex(x, y, z));
- }
- else if ("vn" == ele_id) { // normal data
- is >> x >> y >> z;
- if(!is.good()) { // in case it is -1#IND00
- x = y = z = 0.0;
- is.clear();
- skipLine(is);
- }
- pMesh->addNormal(SVertex(x, y, z));
- }
- else if ("f" == ele_id) { // face data
- // face treatment
- // Note: obviously this technique only works for convex polygons with ten verts or less.
- int vi[10]; // vertex indices.
- int ni[10] = { -1, -1, -1, -1, }; // normal indices.
- int ti[10] = { -1, -1, -1, -1, }; // tex indices.
- int i = 0;
- for (char c; i<10; ++i) {
- if(!pMesh->hasTextureCoords() && !pMesh->hasNormals())
- is >> vi[i];
- else if(!pMesh->hasTextureCoords())
- is >> vi[i] >> c >> c >> ni[i];
- else if(!pMesh->hasNormals())
- is >> vi[i] >> c >> ti[i];
- else
- is >> vi[i] >> c >> ti[i] >> c >> ni[i];
- if(!is.good())
- break;
- }
- // Create the polygon face
- SPolygonFace face;
- for (int k=0; k < i; ++k)
- face.addVertTexNorm(vi[k], ti[k], ni[k]);
- pMesh->addFace(face);
- is.clear();
- }
- else
- skipLine(is);
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement