diff --git a/experimental/tinyobj_loader_opt.h b/experimental/tinyobj_loader_opt.h index e6c0b20..6048432 100644 --- a/experimental/tinyobj_loader_opt.h +++ b/experimental/tinyobj_loader_opt.h @@ -1238,6 +1238,8 @@ typedef struct { // 3. Do parallel parsing for each line. // 4. Reconstruct final mesh data structure. +// Raise # of max threads if you have more CPU cores... +// In 2018, 32 cores are getting common in high-end workstaion PC. #define kMaxThreads (32) static inline bool is_line_ending(const char *p, size_t i, size_t end_i) { diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index 025f112..d52e97c 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -1789,6 +1789,10 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, unsigned int current_smoothing_id = 0; // Initial value. 0 means no smoothing. + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; + shape_t shape; size_t line_num = 0; @@ -1907,6 +1911,10 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, return false; } + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; + face.vertex_indices.push_back(vi); size_t n = strspn(token, " \t\r"); token += n; @@ -2153,6 +2161,31 @@ bool LoadObj(attrib_t *attrib, std::vector *shapes, // Ignore unknown command. } + if (greatest_v_idx >= static_cast(v.size() / 3)) + { + if (err) { + std::stringstream ss; + ss << "WARN: Vertex indices out of bounds.\n" << std::endl; + (*err) += ss.str(); + } + } + if (greatest_vn_idx >= static_cast(vn.size() / 3)) + { + if (err) { + std::stringstream ss; + ss << "WARN: Vertex normal indices out of bounds.\n" << std::endl; + (*err) += ss.str(); + } + } + if (greatest_vt_idx >= static_cast(vt.size() / 2)) + { + if (err) { + std::stringstream ss; + ss << "WARN: Vertex texcoord indices out of bounds.\n" << std::endl; + (*err) += ss.str(); + } + } + bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name, triangulate, v); // exportGroupsToShape return false when `usemtl` is called in the last