// Close the input file and throw an ExceptionParseError exception. void parse_error() { const size_t line_number = m_lexer.get_line_number(); m_lexer.close(); throw ExceptionParseError(line_number); }
void parse_f_statement() { clear_keep_memory(m_face_vertex_indices); clear_keep_memory(m_face_tex_coord_indices); clear_keep_memory(m_face_normal_indices); while (true) { m_lexer.eat_blanks(); if (m_lexer.is_eol()) break; // // Recognized (epsilon) // Accept n // { const long n = m_lexer.accept_long(); const size_t v = fix_index(n, m_vertices.size()); m_face_vertex_indices.push_back(v); } // // Recognized n // Accept (epsilon), / // { const unsigned char c = m_lexer.get_char(); if (m_lexer.is_space(c)) continue; else if (c == '/') m_lexer.next_char(); else parse_error(); } // // Recognized n/ // Accept /, n // { const unsigned char c = m_lexer.get_char(); if (c == '/') { m_lexer.next_char(); goto skip; } else { const long n = m_lexer.accept_long(); const size_t vt = fix_index(n, m_tex_coords.size()); m_face_tex_coord_indices.push_back(vt); } } // // Recognized n/n // Accept (epsilon), / // { const unsigned char c = m_lexer.get_char(); if (m_lexer.is_space(c)) continue; else if (c == '/') m_lexer.next_char(); else parse_error(); } skip: // // Recognized n//, n/n/ // Accept (epsilon), n // { const unsigned char c = m_lexer.get_char(); if (m_lexer.is_space(c)) continue; else { const long n = m_lexer.accept_long(); const size_t vn = fix_index(n, m_normals.size()); m_face_normal_indices.push_back(vn); } } } // Check whether the face is well-formed. const size_t vc = m_face_vertex_indices.size(); const size_t tc = m_face_tex_coord_indices.size(); const size_t nc = m_face_normal_indices.size(); const bool well_formed = vc >= 3 && (tc == 0 || tc == vc) && (nc == 0 || nc == vc); if (well_formed) { // The face is well-formed, insert it into the mesh. insert_face_into_mesh(); } else { // The face is ill-formed, ignore it or abort parsing. if (m_options & StopOnInvalidFaceDef) throw ExceptionInvalidFaceDef(m_lexer.get_line_number()); } }