1

So I'm writing a Wavefront OBJ loader. I was able to get the vertex, normals, and texture coordinates, but I'm having problems with the faces. I'm trying to figure how to ignore certain characters, like "//" and "/" in C++ using std::stringstream. Is there anyway to do this? Thanks.

Here's my load function:

bool Model::load(std::string file_name) {
   std::string line; 
   std::ifstream file(file_name.c_str());
   if(file.is_open()) 
   {
      while(std::getline(file, line))
      {  
        std::stringstream stream(line);
        stream >> line;

        if(line == "#") 
        {
            // ignore.
        }
        if(line == "v") // vertices
        { 
            double x, y, z;
            stream >> x >> y >> z;
            v.push_back(x);
            v.push_back(y);
            v.push_back(z);
            #ifdef DEBUG
            std::cout << "v " << x << " "<< y << " " << z << "\n";
            #endif
        }
        if(line == "vt") // texture coordinates
        {
            double u, v;
            stream >> u >> v;
            vt.push_back(u);
            vt.push_back(v);
            #ifdef DEBUG
            std::cout << "vt " << u << " "<< v << "\n";
            #endif
        }
        if(line == "vn") // normals
        {
            double x, y, z;
            stream >> x >> y >> z;
            vn.push_back(x);
            vn.push_back(y);
            vn.push_back(z);
            #ifdef DEBUG
            std::cout << "vn " << x << " "<< y << " " << z << "\n";
            #endif
        }
        if(line == "f")
        {
           short a, b, c;
           stream >> a; stream >> b; stream >> c;
           a--; b--; c--;

           f.push_back(a);
           f.push_back(b);
           f.push_back(c);

           std::cout << a << " " << b << " " << c << "\n";              
        }

    }
    file.close();
    return true;    
  } return false;
}
BDL
  • 21,052
  • 22
  • 49
  • 55

2 Answers2

2

You could try checking for the characters you don't want directly. In the if statement you could put continue or break or nothing depending on what you want to do.

if (line == "/" || line == "//") {

    continue; //if you want to move on to the next loop iteration

    break;    //if you want to leave the loop

    //Do nothing if you want to continue in the current loop iteration
}
Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175
NeverAgain
  • 66
  • 1
  • 7
0

With your approach you may use a specific locale to determine the delimiters for the >> operator - which is pretty nasty as described here.

In my parser I try to read the first tripplet ("V" or "V/VT" or "V//VN" or "V/VT/VN") parsing character by character, then split the rest of the string expecting the same number of / per vertex - which I found to be quite robust.

Community
  • 1
  • 1
BeyelerStudios
  • 4,243
  • 19
  • 38