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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }