parse face
| 198 | |
| 199 | // parse face |
| 200 | void OBJReader::parseFace(const char * begin, const char * end) |
| 201 | { |
| 202 | vector<int> vec; |
| 203 | vector<int> tvec; |
| 204 | vector<int> nvec; |
| 205 | |
| 206 | srule entry = int_p[append(vec)] >> |
| 207 | ( |
| 208 | ("/" >> (int_p[append(tvec)] | epsilon_p) >> "/" >> (int_p[append(nvec)] | epsilon_p)) |
| 209 | | epsilon_p |
| 210 | ); |
| 211 | |
| 212 | srule face = "f" >> entry >> entry >> entry >> *(entry); |
| 213 | parse(begin, face, space_p); |
| 214 | |
| 215 | // push back the degree of the face |
| 216 | m_vpf->push_back(vec.size()); |
| 217 | |
| 218 | // merge in the edges. we index from 0, so shift them down. |
| 219 | // also, vertices may be indexed negatively, in which case they are relative to |
| 220 | // the current set of vertices |
| 221 | for(vector<int>::const_iterator i = vec.begin(); i != vec.end(); ++i) |
| 222 | { |
| 223 | m_vids->push_back(*i > 0 ? *i - 1 : m_vertices->size() + *i); |
| 224 | } |
| 225 | |
| 226 | |
| 227 | // merge in texture coordinates and normals, if present |
| 228 | // OBJ format requires an encoding for faces which uses one of the vertex/texture/normal specifications |
| 229 | // consistently across the entire face. eg. we can have all v/vt/vn, or all v//vn, or all v, but not |
| 230 | // v//vn then v/vt/vn ... |
| 231 | if(!nvec.empty()) |
| 232 | { |
| 233 | if(nvec.size() != vec.size()) |
| 234 | throw Exception("invalid face specification"); |
| 235 | |
| 236 | // copy in these references to normal vectors to the mesh's normal vector |
| 237 | for(vector<int>::const_iterator i = nvec.begin(); i != nvec.end(); ++i) |
| 238 | { |
| 239 | m_normals->push_back(m_introducedNormals[*i > 0 ? *i - 1 : m_introducedNormals.size() + *i]); |
| 240 | } |
| 241 | } |
| 242 | // otherwise, check if we have specified normals in some previous face |
| 243 | // if so, and no normals were given here (examples, encoders that do this?), pump in |
| 244 | // default normal. the default normal defined here is the zero normal, which is by |
| 245 | // definition orthogonal to every other vector. this might result in odd lighting. |
| 246 | else |
| 247 | { |
| 248 | V3f zero(0.0f, 0.0f, 0.0f); |
| 249 | for(unsigned int i = 0; i < nvec.size(); ++i) |
| 250 | { |
| 251 | m_normals->push_back(zero); |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | // |
| 256 | // merge in texture coordinates, if present |
| 257 | // |