obj_parser.cpp
Go to the documentation of this file.
00001 #include <obj/obj_parser.hpp>
00002 
00003 #include <fstream>
00004 #include <sstream>
00005 
00006 bool obj::obj_parser::parse(std::istream& istream)
00007 {
00008   std::string line;
00009   std::size_t line_number = 0;
00010 
00011   std::size_t number_of_geometric_vertices = 0, number_of_texture_vertices = 0, number_of_vertex_normals = 0, number_of_faces = 0, number_of_group_names = 0, number_of_smoothing_groups = 0, number_of_object_names = 0, number_of_material_libraries = 0, number_of_material_names = 0;
00012 
00013   while (!istream.eof() && std::getline(istream, line)) {
00014     ++line_number;
00015     std::istringstream stringstream(line);
00016     stringstream.unsetf(std::ios_base::skipws);
00017 
00018     stringstream >> std::ws;
00019     if (stringstream.eof()) {
00020       if (flags_ & parse_blank_lines_as_comment) {
00021         if (comment_callback_) {
00022           comment_callback_(line);
00023         }
00024       }
00025     }
00026     else if (stringstream.peek() == '#') {
00027       if (comment_callback_) {
00028         comment_callback_(line);
00029       }
00030     }
00031     else {
00032       std::string keyword;
00033       stringstream >> keyword;
00034 
00035       // geometric vertex (v)
00036       if (keyword == "v") {
00037         float_type x, y, z;
00038         char whitespace_v_x, whitespace_x_y, whitespace_y_z;
00039         stringstream >> whitespace_v_x >> std::ws >> x >> whitespace_x_y >> std::ws >> y >> whitespace_y_z >> std::ws >> z >> std::ws;
00040         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_v_x) || !std::isspace(whitespace_x_y) || !std::isspace(whitespace_y_z)) {
00041           if (error_callback_) {
00042             error_callback_(line_number, "parse error");
00043           }
00044           return false;
00045         }
00046         ++number_of_geometric_vertices;
00047         if (geometric_vertex_callback_) {
00048           geometric_vertex_callback_(x, y, z);
00049         }
00050       }
00051 
00052       // texture vertex (vt)
00053       else if (keyword == "vt") {
00054         float_type u, v;
00055         char whitespace_vt_u, whitespace_u_v;
00056         stringstream >> whitespace_vt_u >> std::ws >> u >> whitespace_u_v >> std::ws >> v;
00057         char whitespace_v_w = ' ';
00058         if (!stringstream.eof()) {
00059           stringstream >> whitespace_v_w >> std::ws;
00060         }
00061         if (!stringstream || !std::isspace(whitespace_vt_u) || !std::isspace(whitespace_u_v) || !std::isspace(whitespace_v_w)) {
00062           if (error_callback_) {
00063             error_callback_(line_number, "parse error");
00064           }
00065           return false;
00066         }
00067         if (stringstream.eof()) {
00068           ++number_of_texture_vertices;
00069           if (texture_vertex_callback_) {
00070             texture_vertex_callback_(u, v);
00071           }
00072         }
00073         else {
00074           float_type w;
00075           stringstream >> w >> std::ws;
00076           if (!stringstream || !stringstream.eof()) {
00077             if (error_callback_) {
00078               error_callback_(line_number, "parse error");
00079             }
00080             return false;
00081           }
00082           ++number_of_texture_vertices;
00083           if (w == float_type(0.0)) {
00084             if (texture_vertex_callback_) {
00085               texture_vertex_callback_(u, v);
00086             }
00087           }
00088           else {
00089             if (error_callback_) {
00090               error_callback_(line_number, "parse error");
00091             }
00092             return false;
00093           }
00094         }
00095       }
00096 
00097       // vertex normal (vn)
00098       else if (keyword == "vn") {
00099         float_type x, y, z;
00100         char whitespace_vn_x, whitespace_x_y, whitespace_y_z;
00101         stringstream >> whitespace_vn_x >> std::ws >> x >> whitespace_x_y >> std::ws >> y >> whitespace_y_z >> std::ws >> z >> std::ws;
00102         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_vn_x) || !std::isspace(whitespace_x_y) || !std::isspace(whitespace_y_z)) {
00103           if (error_callback_) {
00104             error_callback_(line_number, "parse error");
00105           }
00106           return false;
00107         }
00108         ++number_of_vertex_normals;
00109         if (vertex_normal_callback_) {
00110           vertex_normal_callback_(x, y, z);
00111         }
00112       }
00113 
00114       // face (f)
00115       else if ((keyword == "f") || (keyword == "fo")) {
00116         index_type v1;
00117         char whitespace_f_v1;
00118         stringstream >> whitespace_f_v1 >> std::ws >> v1;
00119         if (std::isspace(stringstream.peek())) {
00120           // f v
00121           index_type v2, v3;
00122           char whitespace_v1_v2, whitespace_v2_v3;
00123           stringstream >> whitespace_v1_v2 >> std::ws >> v2 >> whitespace_v2_v3 >> std::ws >> v3;
00124           char whitespace_v3_v4 = ' ';
00125           if (!stringstream.eof()) {
00126             stringstream >> whitespace_v3_v4 >> std::ws;
00127           }
00128           if (!stringstream || !std::isspace(whitespace_f_v1) || !std::isspace(whitespace_v1_v2) || !std::isspace(whitespace_v2_v3) || !std::isspace(whitespace_v3_v4)) {
00129             if (error_callback_) {
00130               error_callback_(line_number, "parse error");
00131             }
00132             return false;
00133           }
00134           if (((v1 < index_type(-number_of_geometric_vertices)) || (-1 < v1)) && ((v1 < 1) || (index_type(number_of_geometric_vertices) < v1))
00135            || ((v2 < index_type(-number_of_geometric_vertices)) || (-1 < v2)) && ((v2 < 1) || (index_type(number_of_geometric_vertices) < v2))
00136            || ((v3 < index_type(-number_of_geometric_vertices)) || (-1 < v3)) && ((v3 < 1) || (index_type(number_of_geometric_vertices) < v3))) {
00137             if (error_callback_) {
00138               error_callback_(line_number, "index out of bounds");
00139             }
00140             return false;
00141           }
00142           if (flags_ & translate_negative_indices) {
00143             if (v1 < 0) {
00144               v1 += number_of_geometric_vertices + 1;
00145             }
00146             if (v2 < 0) {
00147               v2 += number_of_geometric_vertices + 1;
00148             }
00149             if (v3 < 0) {
00150               v3 += number_of_geometric_vertices + 1;
00151             }
00152           }
00153           if (stringstream.eof()) {
00154             ++number_of_faces;
00155             if (triangular_face_geometric_vertices_callback_) {
00156               triangular_face_geometric_vertices_callback_(v1, v2, v3);
00157             }
00158           }
00159           else {
00160             index_type v4;
00161             stringstream >> v4;
00162             char whitespace_v4_v5 = ' ';
00163             if (!stringstream.eof()) {
00164               stringstream >> whitespace_v4_v5 >> std::ws;
00165             }
00166             if (!stringstream || !std::isspace(whitespace_v4_v5)) {
00167               if (error_callback_) {
00168                 error_callback_(line_number, "parse error");
00169               }
00170               return false;
00171             }
00172             if (((v4 < index_type(-number_of_geometric_vertices)) || (-1 < v4)) && ((v4 < 1) || (index_type(number_of_geometric_vertices) < v4))) {
00173               if (error_callback_) {
00174                 error_callback_(line_number, "index out of bounds");
00175               }
00176               return false;
00177             }
00178             if (flags_ & translate_negative_indices) {
00179               if (v4 < 0) {
00180                 v4 += number_of_geometric_vertices + 1;
00181               }
00182             }
00183             if (stringstream.eof()) {
00184               ++number_of_faces;
00185               if (flags_ & triangulate_faces) {
00186                 if (triangular_face_geometric_vertices_callback_) {
00187                   triangular_face_geometric_vertices_callback_(v1, v2, v3);
00188                   triangular_face_geometric_vertices_callback_(v1, v3, v4);
00189                 }
00190               }
00191               else {
00192                 if (quadrilateral_face_geometric_vertices_callback_) {
00193                   quadrilateral_face_geometric_vertices_callback_(v1, v2, v3, v4);
00194                 }
00195               }
00196             }
00197             else {
00198               if (flags_ & triangulate_faces) {
00199                 if (triangular_face_geometric_vertices_callback_) {
00200                   triangular_face_geometric_vertices_callback_(v1, v2, v3);
00201                   triangular_face_geometric_vertices_callback_(v1, v3, v4);
00202                 }
00203                 index_type v_previous = v4;
00204                 do {
00205                   index_type v;
00206                   stringstream >> v;
00207                   char whitespace_v_v = ' ';
00208                   if (!stringstream.eof()) {
00209                     stringstream >> whitespace_v_v >> std::ws;
00210                   }
00211                   if (stringstream && std::isspace(whitespace_v_v)) {
00212                     if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))) {
00213                       if (error_callback_) {
00214                         error_callback_(line_number, "index out of bounds");
00215                       }
00216                       return false;
00217                     }
00218                     if (flags_ & translate_negative_indices) {
00219                       if (v < 0) {
00220                         v += number_of_geometric_vertices + 1;
00221                       }
00222                     }
00223                     if (triangular_face_geometric_vertices_callback_) {
00224                       triangular_face_geometric_vertices_callback_(v1, v_previous, v); 
00225                     }
00226                     v_previous = v;
00227                   }
00228                 }
00229                 while (stringstream && !stringstream.eof());
00230                 if (!stringstream || !stringstream.eof()) {
00231                   if (error_callback_) {
00232                     error_callback_(line_number, "parse error");
00233                   }
00234                   return false;
00235                 }
00236                 ++number_of_faces;
00237               }
00238               else {
00239                 if (polygonal_face_geometric_vertices_begin_callback_) {
00240                   polygonal_face_geometric_vertices_begin_callback_(v1, v2, v3);
00241                 }
00242                 if (polygonal_face_geometric_vertices_vertex_callback_) {
00243                   polygonal_face_geometric_vertices_vertex_callback_(v4);
00244                 }
00245                 do {
00246                   index_type v;
00247                   stringstream >> v;
00248                   char whitespace_v_v = ' ';
00249                   if (!stringstream.eof()) {
00250                     stringstream >> whitespace_v_v >> std::ws;
00251                   }
00252                   if (stringstream && std::isspace(whitespace_v_v)) {
00253                     if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))) {
00254                       if (error_callback_) {
00255                         error_callback_(line_number, "index out of bounds");
00256                       }
00257                       return false;
00258                     }
00259                     if (flags_ & translate_negative_indices) {
00260                       if (v < 0) {
00261                         v += number_of_geometric_vertices + 1;
00262                       }
00263                     }
00264                     if (polygonal_face_geometric_vertices_vertex_callback_) {
00265                       polygonal_face_geometric_vertices_vertex_callback_(v);
00266                     }
00267                   }
00268                 }
00269                 while (stringstream && !stringstream.eof());
00270                 if (!stringstream || !stringstream.eof()) {
00271                   if (error_callback_) {
00272                     error_callback_(line_number, "parse error");
00273                   }
00274                   return false;
00275                 }
00276                 ++number_of_faces;
00277                 if (polygonal_face_geometric_vertices_end_callback_) {
00278                   polygonal_face_geometric_vertices_end_callback_();
00279                 }
00280               }
00281             }
00282           }
00283         }
00284         else {
00285           char slash_v1_vt1;
00286           stringstream >> slash_v1_vt1;
00287           if (stringstream.peek() != '/') {
00288             index_type vt1;
00289             stringstream >> vt1;
00290             if (std::isspace(stringstream.peek())) {
00291               // f v/vt
00292               index_type v2, vt2, v3, vt3;
00293               char whitespace_vt1_v2, slash_v2_vt2, whitespace_vt2_v3, slash_v3_vt3;
00294               stringstream >> whitespace_vt1_v2 >> std::ws >> v2 >> slash_v2_vt2 >> vt2 >> whitespace_vt2_v3 >> std::ws >> v3 >> slash_v3_vt3 >> vt3;
00295               char whitespace_vt3_v4 = ' ';
00296               if (!stringstream.eof()) {
00297                 stringstream >> whitespace_vt3_v4 >> std::ws;
00298               }
00299               if (!stringstream || !std::isspace(whitespace_f_v1) || !(slash_v1_vt1 == '/') || !std::isspace(whitespace_vt1_v2) || !(slash_v2_vt2 == '/') || !std::isspace(whitespace_vt2_v3) || !(slash_v3_vt3 == '/') || !std::isspace(whitespace_vt3_v4)) {
00300                 if (error_callback_) {
00301                   error_callback_(line_number, "parse error");
00302                 }
00303                 return false;
00304               }
00305               if (((v1 < index_type(-number_of_geometric_vertices)) || (-1 < v1)) && ((v1 < 1) || (index_type(number_of_geometric_vertices) < v1))
00306                || ((vt1 < -index_type(number_of_texture_vertices)) || (-1 < vt1)) && ((vt1 < 1) || (index_type(number_of_texture_vertices) < vt1))
00307                || ((v2 < index_type(-number_of_geometric_vertices)) || (-1 < v2)) && ((v2 < 1) || (index_type(number_of_geometric_vertices) < v2))
00308                || ((vt2 < -index_type(number_of_texture_vertices)) || (-1 < vt2)) && ((vt2 < 1) || (index_type(number_of_texture_vertices) < vt2))
00309                || ((v3 < index_type(-number_of_geometric_vertices)) || (-1 < v3)) && ((v3 < 1) || (index_type(number_of_geometric_vertices) < v3))
00310                || ((vt3 < -index_type(number_of_texture_vertices)) || (-1 < vt3)) && ((vt3 < 1) || (index_type(number_of_texture_vertices) < vt3))) {
00311                 if (error_callback_) {
00312                   error_callback_(line_number, "index out of bounds");
00313                 }
00314                 return false;
00315               }
00316               if (flags_ & translate_negative_indices) {
00317                 if (v1 < 0) {
00318                   v1 += number_of_geometric_vertices + 1;
00319                 }
00320                 if (vt1 < 0) {
00321                   vt1 += number_of_texture_vertices + 1;
00322                 }
00323                 if (v2 < 0) {
00324                   v2 += number_of_geometric_vertices + 1;
00325                 }
00326                 if (vt2 < 0) {
00327                   vt2 += number_of_texture_vertices + 1;
00328                 }
00329                 if (v3 < 0) {
00330                   v3 += number_of_geometric_vertices + 1;
00331                 }
00332                 if (vt3 < 0) {
00333                   vt3 += number_of_texture_vertices + 1;
00334                 }
00335               }
00336               if (stringstream.eof()) {
00337                 ++number_of_faces;
00338                 if (triangular_face_geometric_vertices_texture_vertices_callback_) {
00339                   triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v2, vt2), std::tr1::make_tuple(v3, vt3));
00340                 }
00341               }
00342               else {
00343                 index_type v4, vt4;
00344                 char slash_v4_vt4;
00345                 stringstream >> v4 >> slash_v4_vt4 >> vt4;
00346                 char whitespace_vt4_v5 = ' ';
00347                 if (!stringstream.eof()) {
00348                   stringstream >> whitespace_vt4_v5 >> std::ws;
00349                 }
00350                 if (!stringstream || !(slash_v4_vt4 == '/') || !std::isspace(whitespace_vt4_v5)) {
00351                   if (error_callback_) {
00352                     error_callback_(line_number, "parse error");
00353                   }
00354                   return false;
00355                 }
00356                 if (((v4 < index_type(-number_of_geometric_vertices)) || (-1 < v4)) && ((v4 < 1) || (index_type(number_of_geometric_vertices) < v4))
00357                 || ((vt4 < -index_type(number_of_texture_vertices)) || (-1 < vt4)) && ((vt4 < 1) || (index_type(number_of_texture_vertices) < vt4))) {
00358                   if (error_callback_) {
00359                     error_callback_(line_number, "index out of bounds");
00360                   }
00361                   return false;
00362                 }
00363                 if (flags_ & translate_negative_indices) {
00364                   if (v4 < 0) {
00365                     v4 += number_of_geometric_vertices + 1;
00366                   }
00367                   if (vt4 < 0) {
00368                     vt4 += number_of_texture_vertices + 1;
00369                   }
00370                 }
00371                 if (stringstream.eof()) {
00372                   ++number_of_faces;
00373                   if (flags_ & triangulate_faces) {
00374                     if (triangular_face_geometric_vertices_texture_vertices_callback_) {
00375                       triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v2, vt2), std::tr1::make_tuple(v3, vt3));
00376                       triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v3, vt3), std::tr1::make_tuple(v4, vt4));
00377                     }
00378                   }
00379                   else {
00380                     if (quadrilateral_face_geometric_vertices_texture_vertices_callback_) {
00381                       quadrilateral_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v2, vt2), std::tr1::make_tuple(v3, vt3), std::tr1::make_tuple(v4, vt4));
00382                     }
00383                   }
00384                 }
00385                 else {
00386                   if (flags_ & triangulate_faces) {
00387                     if (triangular_face_geometric_vertices_texture_vertices_callback_) {
00388                       triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v2, vt2), std::tr1::make_tuple(v3, vt3));
00389                       triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v3, vt3), std::tr1::make_tuple(v4, vt4));
00390                     }
00391                     index_type v_previous = v4, vt_previous = vt4;
00392                     do {
00393                       index_type v, vt;
00394                       char slash_geometric_vertices_texture_vertices;
00395                       stringstream >> v >> slash_geometric_vertices_texture_vertices >> vt;
00396                       char whitespace_vt_v = ' ';
00397                       if (!stringstream.eof()) {
00398                         stringstream >> whitespace_vt_v >> std::ws;
00399                       }
00400                       if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && std::isspace(whitespace_vt_v)) {
00401                         if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00402                         || ((vt < -index_type(number_of_texture_vertices)) || (-1 < vt)) && ((vt < 1) || (index_type(number_of_texture_vertices) < vt))) {
00403                           if (error_callback_) {
00404                             error_callback_(line_number, "index out of bounds");
00405                           }
00406                           return false;
00407                         }
00408                         if (flags_ & translate_negative_indices) {
00409                           if (v < 0) {
00410                             v += number_of_geometric_vertices + 1;
00411                           }
00412                           if (vt < 0) {
00413                             vt += number_of_texture_vertices + 1;
00414                           }
00415                         }
00416                         if (triangular_face_geometric_vertices_texture_vertices_callback_) {
00417                           triangular_face_geometric_vertices_texture_vertices_callback_(std::tr1::make_tuple(v1, vt1), std::tr1::make_tuple(v_previous, vt_previous), std::tr1::make_tuple(v, vt));
00418                         }
00419                         v_previous = v, vt_previous = vt;
00420                       }
00421                     }
00422                     while (stringstream && !stringstream.eof());
00423                     if (!stringstream || !stringstream.eof()) {
00424                       if (error_callback_) {
00425                         error_callback_(line_number, "parse error");
00426                       }
00427                       return false;
00428                     }
00429                     ++number_of_faces;
00430                   }
00431                   else {
00432                     if (polygonal_face_geometric_vertices_texture_vertices_begin_callback_) {
00433                       polygonal_face_geometric_vertices_texture_vertices_begin_callback_(index_2_tuple_type(v1, vt1), index_2_tuple_type(v2, vt2), index_2_tuple_type(v3, vt3));
00434                     }
00435                     if (polygonal_face_geometric_vertices_texture_vertices_vertex_callback_) {
00436                       polygonal_face_geometric_vertices_texture_vertices_vertex_callback_(index_2_tuple_type(v4, vt4));
00437                     }
00438                     do {
00439                       index_type v, vt;
00440                       char slash_geometric_vertices_texture_vertices;
00441                       stringstream >> v >> slash_geometric_vertices_texture_vertices >> vt;
00442                       char whitespace_vt_v = ' ';
00443                       if (!stringstream.eof()) {
00444                         stringstream >> whitespace_vt_v >> std::ws;
00445                       }
00446                       if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && std::isspace(whitespace_vt_v)) {
00447                         if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00448                         || ((vt < -index_type(number_of_texture_vertices)) || (-1 < vt)) && ((vt < 1) || (index_type(number_of_texture_vertices) < vt))) {
00449                           if (error_callback_) {
00450                             error_callback_(line_number, "index out of bounds");
00451                           }
00452                           return false;
00453                         }
00454                         if (flags_ & translate_negative_indices) {
00455                           if (v < 0) {
00456                             v += number_of_geometric_vertices + 1;
00457                           }
00458                           if (vt < 0) {
00459                             vt += number_of_texture_vertices + 1;
00460                           }
00461                         }
00462                         if (polygonal_face_geometric_vertices_texture_vertices_vertex_callback_) {
00463                           polygonal_face_geometric_vertices_texture_vertices_vertex_callback_(index_2_tuple_type(v, vt));
00464                         }
00465                       }
00466                     }
00467                     while (stringstream && !stringstream.eof());
00468                     if (!stringstream || !stringstream.eof()) {
00469                       if (error_callback_) {
00470                         error_callback_(line_number, "parse error");
00471                       }
00472                       return false;
00473                     }
00474                     ++number_of_faces;
00475                     if (polygonal_face_geometric_vertices_texture_vertices_end_callback_) {
00476                       polygonal_face_geometric_vertices_texture_vertices_end_callback_();
00477                     }
00478                   }
00479                 }
00480               }
00481             }
00482             else {
00483               // f v/vt/vn
00484               index_type vn1, v2, vt2, vn2, v3, vt3, vn3;
00485               char slash_vt1_vn1, whitespace_vn1_v2, slash_v2_vt2, slash_vt2_vn2, whitespace_vn2_v3, slash_v3_vt3, slash_vt3_vn3;
00486               stringstream >> slash_vt1_vn1 >> vn1 >> whitespace_vn1_v2 >> std::ws >> v2 >> slash_v2_vt2 >> vt2 >> slash_vt2_vn2 >> vn2 >> whitespace_vn2_v3 >> std::ws >> v3 >> slash_v3_vt3 >> vt3 >> slash_vt3_vn3 >> vn3;
00487               char whitespace_vn3_v4 = ' ';
00488               if (!stringstream.eof()) {
00489                 stringstream >> whitespace_vn3_v4 >> std::ws;
00490               }
00491               if (!stringstream || !std::isspace(whitespace_f_v1) || !(slash_v1_vt1 == '/') || !(slash_vt1_vn1 == '/') || !std::isspace(whitespace_vn1_v2) || !(slash_v2_vt2 == '/') || !(slash_vt2_vn2 == '/') || !std::isspace(whitespace_vn2_v3) || !(slash_v3_vt3 == '/') || !(slash_vt3_vn3 == '/') || !std::isspace(whitespace_vn3_v4)) {
00492                 if (error_callback_) {
00493                   error_callback_(line_number, "parse error");
00494                 }
00495                 return false;
00496               }
00497               if (((v1 < index_type(-number_of_geometric_vertices)) || (-1 < v1)) && ((v1 < 1) || (index_type(number_of_geometric_vertices) < v1))
00498                || ((vt1 < -index_type(number_of_texture_vertices)) || (-1 < vt1)) && ((vt1 < 1) || (index_type(number_of_texture_vertices) < vt1))
00499                || ((vn1 < -index_type(number_of_vertex_normals)) || (-1 < vn1)) && ((vn1 < 1) || (index_type(number_of_vertex_normals) < vn1))
00500                || ((v2 < index_type(-number_of_geometric_vertices)) || (-1 < v2)) && ((v2 < 1) || (index_type(number_of_geometric_vertices) < v2))
00501                || ((vt2 < -index_type(number_of_texture_vertices)) || (-1 < vt2)) && ((vt2 < 1) || (index_type(number_of_texture_vertices) < vt2))
00502                || ((vn2 < -index_type(number_of_vertex_normals)) || (-1 < vn2)) && ((vn2 < 1) || (index_type(number_of_vertex_normals) < vn2))
00503                || ((v3 < index_type(-number_of_geometric_vertices)) || (-1 < v3)) && ((v3 < 1) || (index_type(number_of_geometric_vertices) < v3))
00504                || ((vt3 < -index_type(number_of_texture_vertices)) || (-1 < vt3)) && ((vt3 < 1) || (index_type(number_of_texture_vertices) < vt3))
00505                || ((vn3 < -index_type(number_of_vertex_normals)) || (-1 < vn3)) && ((vn3 < 1) || (index_type(number_of_vertex_normals) < vn3))) {
00506                 if (error_callback_) {
00507                   error_callback_(line_number, "index out of bounds");
00508                 }
00509                 return false;
00510               }
00511               if (flags_ & translate_negative_indices) {
00512                 if (v1 < 0) {
00513                   v1 += number_of_geometric_vertices + 1;
00514                 }
00515                 if (vt1 < 0) {
00516                   vt1 += number_of_texture_vertices + 1;
00517                 }
00518                 if (vn1 < 0) {
00519                   vn1 += number_of_vertex_normals + 1;
00520                 }
00521                 if (v2 < 0) {
00522                   v2 += number_of_geometric_vertices + 1;
00523                 }
00524                 if (vt2 < 0) {
00525                   vt2 += number_of_texture_vertices + 1;
00526                 }
00527                 if (vn2 < 0) {
00528                   vn2 += number_of_vertex_normals + 1;
00529                 }
00530                 if (v3 < 0) {
00531                   v3 += number_of_geometric_vertices + 1;
00532                 }
00533                 if (vt3 < 0) {
00534                   vt3 += number_of_texture_vertices + 1;
00535                 }
00536                 if (vn3 < 0) {
00537                   vn3 += number_of_vertex_normals + 1;
00538                 }
00539               }
00540               if (stringstream.eof()) {
00541                 ++number_of_faces;
00542                 if (triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_) {
00543                   triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v2, vt2, vn2), std::tr1::make_tuple(v3, vt3, vn3));
00544                 }
00545               }
00546               else {
00547                 index_type v4, vt4, vn4;
00548                 char slash_v4_vt4, slash_vt4_vn4;
00549                 stringstream >> v4 >> slash_v4_vt4 >> vt4 >> slash_vt4_vn4 >> vn4;
00550                 char whitespace_vn4_v5 = ' ';
00551                 if (!stringstream.eof()) {
00552                   stringstream >> whitespace_vn4_v5 >> std::ws;
00553                 }
00554                 if (!stringstream || !(slash_v4_vt4 == '/') || !(slash_vt4_vn4 == '/') || !std::isspace(whitespace_vn4_v5)) {
00555                   if (error_callback_) {
00556                     error_callback_(line_number, "parse error");
00557                   }
00558                   return false;
00559                 }
00560                 if (((v4 < index_type(-number_of_geometric_vertices)) || (-1 < v4)) && ((v4 < 1) || (index_type(number_of_geometric_vertices) < v4))
00561                  || ((vt4 < -index_type(number_of_texture_vertices)) || (-1 < vt4)) && ((vt4 < 1) || (index_type(number_of_texture_vertices) < vt4))
00562                  || ((vn4 < -index_type(number_of_vertex_normals)) || (-1 < vn4)) && ((vn4 < 1) || (index_type(number_of_vertex_normals) < vn4))) {
00563                   if (error_callback_) {
00564                     error_callback_(line_number, "index out of bounds");
00565                   }
00566                   return false;
00567                 }
00568                 if (flags_ & translate_negative_indices) {
00569                   if (v4 < 0) {
00570                     v4 += number_of_geometric_vertices + 1;
00571                   }
00572                   if (vt4 < 0) {
00573                     vt4 += number_of_texture_vertices + 1;
00574                   }
00575                   if (vn4 < 0) {
00576                     vn4 += number_of_vertex_normals + 1;
00577                   }
00578                 }
00579                 if (stringstream.eof()) {
00580                   ++number_of_faces;
00581                   if (flags_ & triangulate_faces) {
00582                     if (triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_) {
00583                       triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v2, vt2, vn2), std::tr1::make_tuple(v3, vt3, vn3));
00584                       triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v3, vt3, vn3), std::tr1::make_tuple(v4, vt4, vn4));
00585                     }
00586                   }
00587                   else {
00588                     if (quadrilateral_face_geometric_vertices_texture_vertices_vertex_normals_callback_) {
00589                       quadrilateral_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v2, vt2, vn2), std::tr1::make_tuple(v3, vt3, vn3), std::tr1::make_tuple(v4, vt4, vn4));
00590                     }
00591                   }
00592                 }
00593                 else {
00594                   if (flags_ & triangulate_faces) {
00595                     if (triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_) {
00596                       triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v2, vt2, vn2), std::tr1::make_tuple(v3, vt3, vn3));
00597                       triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v3, vt3, vn3), std::tr1::make_tuple(v4, vt4, vn4));
00598                     }
00599                     index_type v_previous = v4, vt_previous = vt4, vn_previous = vn4;
00600                     do {
00601                       index_type v, vt, vn;
00602                       char slash_geometric_vertices_texture_vertices, slash_vt_vn;
00603                       stringstream >> v >> slash_geometric_vertices_texture_vertices >> vt >> slash_vt_vn >> vn;
00604                       char whitespace_vn_v = ' ';
00605                       if (!stringstream.eof()) {
00606                         stringstream >> whitespace_vn_v >> std::ws;
00607                       }
00608                       if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && (slash_vt_vn == '/') && std::isspace(whitespace_vn_v)) {
00609                         if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00610                         || ((vt < -index_type(number_of_texture_vertices)) || (-1 < vt)) && ((vt < 1) || (index_type(number_of_texture_vertices) < vt))
00611                         || ((vn < -index_type(number_of_vertex_normals)) || (-1 < vn)) && ((vn < 1) || (index_type(number_of_vertex_normals) < vn))) {
00612                           if (error_callback_) {
00613                             error_callback_(line_number, "index out of bounds");
00614                           }
00615                           return false;
00616                         }
00617                         if (flags_ & translate_negative_indices) {
00618                           if (v < 0) {
00619                             v += number_of_geometric_vertices + 1;
00620                           }
00621                           if (vt < 0) {
00622                             vt += number_of_texture_vertices + 1;
00623                           }
00624                           if (vn < 0) {
00625                             vn += number_of_vertex_normals + 1;
00626                           }
00627                         }
00628                         if (triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_) {
00629                           triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vt1, vn1), std::tr1::make_tuple(v_previous, vt_previous, vn_previous), std::tr1::make_tuple(v, vt, vn));
00630                         }
00631                         v_previous = v, vt_previous = vt, vn_previous = vn;
00632                       }
00633                     }
00634                     while (stringstream && !stringstream.eof());
00635                     if (!stringstream || !stringstream.eof()) {
00636                       if (error_callback_) {
00637                         error_callback_(line_number, "parse error");
00638                       }
00639                       return false;
00640                     }
00641                     ++number_of_faces;
00642                   }
00643                   else {
00644                     if (polygonal_face_geometric_vertices_texture_vertices_vertex_normals_begin_callback_) {
00645                       polygonal_face_geometric_vertices_texture_vertices_vertex_normals_begin_callback_(index_3_tuple_type(v1, vt1, vn1), index_3_tuple_type(v2, vt2, vn2), index_3_tuple_type(v3, vt3, vn3));
00646                     }
00647                     if (polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback_) {
00648                       polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback_(index_3_tuple_type(v4, vt4, vn4));
00649                     }
00650                     do {
00651                       index_type v, vt, vn;
00652                       char slash_geometric_vertices_texture_vertices, slash_vt_vn;
00653                       stringstream >> v >> slash_geometric_vertices_texture_vertices >> vt >> slash_vt_vn >> vn;
00654                       char whitespace_vn_v = ' ';
00655                       if (!stringstream.eof()) {
00656                         stringstream >> whitespace_vn_v >> std::ws;
00657                       }
00658                       if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && (slash_vt_vn == '/') && std::isspace(whitespace_vn_v)) {
00659                         if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00660                         || ((vt < -index_type(number_of_texture_vertices)) || (-1 < vt)) && ((vt < 1) || (index_type(number_of_texture_vertices) < vt))
00661                         || ((vn < -index_type(number_of_vertex_normals)) || (-1 < vn)) && ((vn < 1) || (index_type(number_of_vertex_normals) < vn))) {
00662                           if (error_callback_) {
00663                             error_callback_(line_number, "index out of bounds");
00664                           }
00665                           return false;
00666                         }
00667                         if (flags_ & translate_negative_indices) {
00668                           if (v < 0) {
00669                             v += number_of_geometric_vertices + 1;
00670                           }
00671                           if (vt < 0) {
00672                             vt += number_of_texture_vertices + 1;
00673                           }
00674                           if (vn < 0) {
00675                             vn += number_of_vertex_normals + 1;
00676                           }
00677                         }
00678                         if (polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback_) {
00679                           polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback_(index_3_tuple_type(v, vt, vn));
00680                         }
00681                       }
00682                     }
00683                     while (stringstream && !stringstream.eof());
00684                     if (!stringstream || !stringstream.eof()) {
00685                       if (error_callback_) {
00686                         error_callback_(line_number, "parse error");
00687                       }
00688                       return false;
00689                     }
00690                     ++number_of_faces;
00691                     if (polygonal_face_geometric_vertices_texture_vertices_vertex_normals_end_callback_) {
00692                       polygonal_face_geometric_vertices_texture_vertices_vertex_normals_end_callback_();
00693                     }
00694                   }
00695                 }
00696               }
00697             }
00698           }
00699           else {
00700             // f v//vn
00701             index_type vn1, v2, vn2, v3, vn3;
00702             char slash_vt1_vn1, whitespace_vn1_v2, slash_v2_vt2, slash_vt2_vn2, whitespace_vn2_v3, slash_v3_vt3, slash_vt3_vn3;
00703             stringstream >> slash_vt1_vn1 >> vn1 >> whitespace_vn1_v2 >> std::ws >> v2 >> slash_v2_vt2 >> slash_vt2_vn2 >> vn2 >> whitespace_vn2_v3 >> std::ws >> v3 >> slash_v3_vt3 >> slash_vt3_vn3 >> vn3;
00704             char whitespace_vn3_v4 = ' ';
00705             if (!stringstream.eof()) {
00706               stringstream >> whitespace_vn3_v4 >> std::ws;
00707             }
00708             if (!stringstream || !std::isspace(whitespace_f_v1) || !(slash_v1_vt1 == '/') || !(slash_vt1_vn1 == '/') || !std::isspace(whitespace_vn1_v2) || !(slash_v2_vt2 == '/') || !(slash_vt2_vn2 == '/') || !std::isspace(whitespace_vn2_v3) || !(slash_v3_vt3 == '/') || !(slash_vt3_vn3 == '/') || !std::isspace(whitespace_vn3_v4)) {
00709               if (error_callback_) {
00710                 error_callback_(line_number, "parse error");
00711               }
00712               return false;
00713             }
00714             if (((v1 < index_type(-number_of_geometric_vertices)) || (-1 < v1)) && ((v1 < 1) || (index_type(number_of_geometric_vertices) < v1))
00715               || ((vn1 < -index_type(number_of_vertex_normals)) || (-1 < vn1)) && ((vn1 < 1) || (index_type(number_of_vertex_normals) < vn1))
00716               || ((v2 < index_type(-number_of_geometric_vertices)) || (-1 < v2)) && ((v2 < 1) || (index_type(number_of_geometric_vertices) < v2))
00717               || ((vn2 < -index_type(number_of_vertex_normals)) || (-1 < vn2)) && ((vn2 < 1) || (index_type(number_of_vertex_normals) < vn2))
00718               || ((v3 < index_type(-number_of_geometric_vertices)) || (-1 < v3)) && ((v3 < 1) || (index_type(number_of_geometric_vertices) < v3))
00719               || ((vn3 < -index_type(number_of_vertex_normals)) || (-1 < vn3)) && ((vn3 < 1) || (index_type(number_of_vertex_normals) < vn3))) {
00720               if (error_callback_) {
00721                 error_callback_(line_number, "index out of bounds");
00722               }
00723               return false;
00724             }
00725             if (flags_ & translate_negative_indices) {
00726               if (v1 < 0) {
00727                 v1 += number_of_geometric_vertices + 1;
00728               }
00729               if (vn1 < 0) {
00730                 vn1 += number_of_vertex_normals + 1;
00731               }
00732               if (v2 < 0) {
00733                 v2 += number_of_geometric_vertices + 1;
00734               }
00735               if (vn2 < 0) {
00736                 vn2 += number_of_vertex_normals + 1;
00737               }
00738               if (v3 < 0) {
00739                 v3 += number_of_geometric_vertices + 1;
00740               }
00741               if (vn3 < 0) {
00742                 vn3 += number_of_vertex_normals + 1;
00743               }
00744             }
00745             if (stringstream.eof()) {
00746               ++number_of_faces;
00747               if (triangular_face_geometric_vertices_vertex_normals_callback_) {
00748                 triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v2, vn2), std::tr1::make_tuple(v3, vn3));
00749               }
00750             }
00751             else {
00752               index_type v4, vn4;
00753               char slash_v4_vt4, slash_vt4_vn4;
00754               stringstream >> v4 >> slash_v4_vt4 >> slash_vt4_vn4 >> vn4;
00755               char whitespace_vn4_v5 = ' ';
00756               if (!stringstream.eof()) {
00757                 stringstream >> whitespace_vn4_v5 >> std::ws;
00758               }
00759               if (!stringstream || !(slash_v4_vt4 == '/') || !(slash_vt4_vn4 == '/') || !std::isspace(whitespace_vn4_v5)) {
00760                 if (error_callback_) {
00761                   error_callback_(line_number, "parse error");
00762                 }
00763                 return false;
00764               }
00765               if (((v4 < index_type(-number_of_geometric_vertices)) || (-1 < v4)) && ((v4 < 1) || (index_type(number_of_geometric_vertices) < v4))
00766                 || ((vn4 < -index_type(number_of_vertex_normals)) || (-1 < vn4)) && ((vn4 < 1) || (index_type(number_of_vertex_normals) < vn4))) {
00767                 if (error_callback_) {
00768                   error_callback_(line_number, "index out of bounds");
00769                 }
00770                 return false;
00771               }
00772               if (flags_ & translate_negative_indices) {
00773                 if (v4 < 0) {
00774                   v4 += number_of_geometric_vertices + 1;
00775                 }
00776                 if (vn4 < 0) {
00777                   vn4 += number_of_vertex_normals + 1;
00778                 }
00779               }
00780               if (stringstream.eof()) {
00781                 ++number_of_faces;
00782                 if (flags_ & triangulate_faces) {
00783                   if (triangular_face_geometric_vertices_vertex_normals_callback_) {
00784                     triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v2, vn2), std::tr1::make_tuple(v3, vn3));
00785                     triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v3, vn3), std::tr1::make_tuple(v4, vn4));
00786                   }
00787                 }
00788                 else {
00789                   if (quadrilateral_face_geometric_vertices_vertex_normals_callback_) {
00790                     quadrilateral_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v2, vn2), std::tr1::make_tuple(v3, vn3), std::tr1::make_tuple(v4, vn4));
00791                   }
00792                 }
00793               }
00794               else {
00795                 if (flags_ & triangulate_faces) {
00796                   if (triangular_face_geometric_vertices_vertex_normals_callback_) {
00797                     triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v2, vn2), std::tr1::make_tuple(v3, vn3));
00798                     triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v3, vn3), std::tr1::make_tuple(v4, vn4));
00799                   }
00800                   index_type v_previous = v4, vn_previous = vn4;
00801                   do {
00802                     index_type v, vn;
00803                     char slash_geometric_vertices_texture_vertices, slash_vt_vn;
00804                     stringstream >> v >> slash_geometric_vertices_texture_vertices >> slash_vt_vn >> vn;
00805                     char whitespace_vn_v = ' ';
00806                     if (!stringstream.eof()) {
00807                       stringstream >> whitespace_vn_v >> std::ws;
00808                     }
00809                     if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && (slash_vt_vn == '/') && std::isspace(whitespace_vn_v)) {
00810                       if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00811                         || ((vn < -index_type(number_of_vertex_normals)) || (-1 < vn)) && ((vn < 1) || (index_type(number_of_vertex_normals) < vn))) {
00812                         if (error_callback_) {
00813                           error_callback_(line_number, "index out of bounds");
00814                         }
00815                         return false;
00816                       }
00817                       if (flags_ & translate_negative_indices) {
00818                         if (v < 0) {
00819                           v += number_of_geometric_vertices + 1;
00820                         }
00821                         if (vn < 0) {
00822                           vn += number_of_vertex_normals + 1;
00823                         }
00824                       }
00825                       if (triangular_face_geometric_vertices_vertex_normals_callback_) {
00826                         triangular_face_geometric_vertices_vertex_normals_callback_(std::tr1::make_tuple(v1, vn1), std::tr1::make_tuple(v_previous, vn_previous), std::tr1::make_tuple(v, vn));
00827                       }
00828                       v_previous = v, vn_previous = vn;
00829                     }
00830                   }
00831                   while (stringstream && !stringstream.eof());
00832                   if (!stringstream || !stringstream.eof()) {
00833                     if (error_callback_) {
00834                       error_callback_(line_number, "parse error");
00835                     }
00836                     return false;
00837                   }
00838                   ++number_of_faces;
00839                 }
00840                 else {
00841                   if (polygonal_face_geometric_vertices_vertex_normals_begin_callback_) {
00842                     polygonal_face_geometric_vertices_vertex_normals_begin_callback_(index_2_tuple_type(v1, vn1), index_2_tuple_type(v2, vn2), index_2_tuple_type(v3, vn3));
00843                   }
00844                   if (polygonal_face_geometric_vertices_vertex_normals_vertex_callback_) {
00845                     polygonal_face_geometric_vertices_vertex_normals_vertex_callback_(index_2_tuple_type(v4, vn4));
00846                   }
00847                   do {
00848                     index_type v, vn;
00849                     char slash_geometric_vertices_texture_vertices, slash_vt_vn;
00850                     stringstream >> v >> slash_geometric_vertices_texture_vertices >> slash_vt_vn >> vn;
00851                     char whitespace_vn_v = ' ';
00852                     if (!stringstream.eof()) {
00853                       stringstream >> whitespace_vn_v >> std::ws;
00854                     }
00855                     if (stringstream && (slash_geometric_vertices_texture_vertices == '/') && (slash_vt_vn == '/') && std::isspace(whitespace_vn_v)) {
00856                       if (((v < index_type(-number_of_geometric_vertices)) || (-1 < v)) && ((v < 1) || (index_type(number_of_geometric_vertices) < v))
00857                         || ((vn < index_type(-number_of_vertex_normals)) || (-1 < vn)) && ((vn < 1) || (index_type(number_of_vertex_normals) < vn))) {
00858                         if (error_callback_) {
00859                           error_callback_(line_number, "index out of bounds");
00860                         }
00861                         return false;
00862                       }
00863                       if (flags_ & translate_negative_indices) {
00864                         if (v < 0) {
00865                           v += number_of_geometric_vertices + 1;
00866                         }
00867                         if (vn < 0) {
00868                           vn += number_of_vertex_normals + 1;
00869                         }
00870                       }
00871                       if (polygonal_face_geometric_vertices_vertex_normals_vertex_callback_) {
00872                         polygonal_face_geometric_vertices_vertex_normals_vertex_callback_(index_2_tuple_type(v, vn));
00873                       }
00874                     }
00875                   }
00876                   while (stringstream && !stringstream.eof());
00877                   if (!stringstream || !stringstream.eof()) {
00878                     if (error_callback_) {
00879                       error_callback_(line_number, "parse error");
00880                     }
00881                     return false;
00882                   }
00883                   ++number_of_faces;
00884                   if (polygonal_face_geometric_vertices_vertex_normals_end_callback_) {
00885                     polygonal_face_geometric_vertices_vertex_normals_end_callback_();
00886                   }
00887                 }
00888               }
00889             }
00890           }
00891         }
00892       }
00893 
00894       // group name (g)
00895       else if (keyword == "g") {
00896         char whitespace_mtllib_group_name = ' ';
00897         if (!stringstream.eof()) {
00898           stringstream >> whitespace_mtllib_group_name >> std::ws;
00899         }
00900         if (!stringstream || !std::isspace(whitespace_mtllib_group_name)) {
00901           if (error_callback_) {
00902             error_callback_(line_number, "parse error");
00903           }
00904           return false;
00905         }
00906         if (stringstream.eof()) {
00907           ++number_of_group_names;
00908           if (group_name_callback_) {
00909             group_name_callback_("default");
00910           }
00911         }
00912         else {
00913           std::string group_name;
00914           stringstream >> group_name >> std::ws;
00915           if (!stringstream || !stringstream.eof()) {
00916             if (error_callback_) {
00917               error_callback_(line_number, "parse error");
00918             }
00919             return false;
00920           }
00921           ++number_of_group_names;
00922           if (group_name_callback_) {
00923             group_name_callback_(group_name);
00924           }
00925         }
00926       }
00927 
00928       // smoothing group (s)
00929       else if (keyword == "s") {
00930         std::string group_number_string;
00931         char whitespace_mtllib_group_number;
00932         stringstream >> whitespace_mtllib_group_number >> std::ws >> group_number_string >> std::ws;
00933         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_mtllib_group_number)) {
00934           if (error_callback_) {
00935             error_callback_(line_number, "parse error");
00936           }
00937           return false;
00938         }
00939         size_type group_number;
00940         if (group_number_string == "off") {
00941           group_number = 0;
00942         }
00943         else {
00944           std::istringstream stringstream(group_number_string);
00945           stringstream >> group_number;
00946           if (!stringstream || !stringstream.eof()) {
00947             if (error_callback_) {
00948               error_callback_(line_number, "parse error");
00949             }
00950             return false;
00951           }
00952         }
00953         ++number_of_smoothing_groups;
00954         if (smoothing_group_callback_) {
00955           smoothing_group_callback_(group_number);
00956         }
00957       }
00958 
00959       // object name (o)
00960       else if (keyword == "o") {
00961         std::string object_name;
00962         char whitespace_mtllib_object_name;
00963         stringstream >> whitespace_mtllib_object_name >> std::ws >> object_name >> std::ws;
00964         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_mtllib_object_name)) {
00965           if (error_callback_) {
00966             error_callback_(line_number, "parse error");
00967           }
00968           return false;
00969         }
00970         ++number_of_object_names;
00971         if (object_name_callback_) {
00972           object_name_callback_(object_name);
00973         }
00974       }
00975 
00976       // material library (mtllib)
00977       else if (keyword == "mtllib") {
00978         std::string filename;
00979         char whitespace_mtllib_filename;
00980         stringstream >> whitespace_mtllib_filename >> std::ws >> filename >> std::ws;
00981         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_mtllib_filename)) {
00982           if (error_callback_) {
00983             error_callback_(line_number, "parse error");
00984           }
00985           return false;
00986         }
00987         ++number_of_material_libraries;
00988         if (material_library_callback_) {
00989           material_library_callback_(filename);
00990         }
00991       }
00992 
00993       // material name (usemtl)
00994       else if (keyword == "usemtl") {
00995         std::string material_name;
00996         char whitespace_mtllib_material_name;
00997         stringstream >> whitespace_mtllib_material_name >> std::ws >> material_name >> std::ws;
00998         if (!stringstream || !stringstream.eof() || !std::isspace(whitespace_mtllib_material_name)) {
00999           if (error_callback_) {
01000             error_callback_(line_number, "parse error");
01001           }
01002           return false;
01003         }
01004         ++number_of_material_names;
01005         if (material_name_callback_) {
01006           material_name_callback_(material_name);
01007         }
01008       }
01009 
01010       // unknown keyword
01011       else {
01012         std::string message = "ignoring line ‘" + line + "’";
01013         if (warning_callback_) {
01014           warning_callback_(line_number, message);
01015         }
01016       }
01017 
01018     }
01019   }
01020 
01021   return istream.fail() && istream.eof() && !istream.bad();
01022 }


libobj
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:19