@@ -796,8 +796,21 @@ static std::istream &safeGetline(std::istream &is, std::string &t) {
796796 (static_cast <unsigned int >((x) - ' 0' ) < static_cast <unsigned int >(10 ))
797797#define IS_NEW_LINE (x ) (((x) == ' \r ' ) || ((x) == ' \n ' ) || ((x) == ' \0 ' ))
798798
799+ template <typename T>
800+ static inline std::string toString (const T &t) {
801+ std::stringstream ss;
802+ ss << t;
803+ return ss.str ();
804+ }
805+
806+ struct warning_context
807+ {
808+ std::string *warn;
809+ size_t line_number;
810+ };
811+
799812// Make index zero-base, and also support relative index.
800- static inline bool fixIndex (int idx, int n, int *ret) {
813+ static inline bool fixIndex (int idx, int n, int *ret, bool allow_zero, const warning_context &context ) {
801814 if (!ret) {
802815 return false ;
803816 }
@@ -809,7 +822,13 @@ static inline bool fixIndex(int idx, int n, int *ret) {
809822
810823 if (idx == 0 ) {
811824 // zero is not allowed according to the spec.
812- return false ;
825+ if (context.warn ) {
826+ (*context.warn ) += " A zero value index found (will have a value of -1 for normal and tex indices. Line "
827+ + toString (context.line_number ) + " ).\n " ;
828+ }
829+
830+ (*ret) = idx - 1 ;
831+ return allow_zero;
813832 }
814833
815834 if (idx < 0 ) {
@@ -1134,14 +1153,14 @@ static tag_sizes parseTagTriple(const char **token) {
11341153
11351154// Parse triples with index offsets: i, i/j/k, i//k, i/j
11361155static bool parseTriple (const char **token, int vsize, int vnsize, int vtsize,
1137- vertex_index_t *ret) {
1156+ vertex_index_t *ret, const warning_context &context ) {
11381157 if (!ret) {
11391158 return false ;
11401159 }
11411160
11421161 vertex_index_t vi (-1 );
11431162
1144- if (!fixIndex (atoi ((*token)), vsize, &( vi.v_idx ) )) {
1163+ if (!fixIndex (atoi ((*token)), vsize, &vi.v_idx , false , context )) {
11451164 return false ;
11461165 }
11471166
@@ -1155,7 +1174,7 @@ static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize,
11551174 // i//k
11561175 if ((*token)[0 ] == ' /' ) {
11571176 (*token)++;
1158- if (!fixIndex (atoi ((*token)), vnsize, &( vi.vn_idx ) )) {
1177+ if (!fixIndex (atoi ((*token)), vnsize, &vi.vn_idx , true , context )) {
11591178 return false ;
11601179 }
11611180 (*token) += strcspn ((*token), " / \t\r " );
@@ -1164,7 +1183,7 @@ static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize,
11641183 }
11651184
11661185 // i/j/k or i/j
1167- if (!fixIndex (atoi ((*token)), vtsize, &( vi.vt_idx ) )) {
1186+ if (!fixIndex (atoi ((*token)), vtsize, &vi.vt_idx , true , context )) {
11681187 return false ;
11691188 }
11701189
@@ -1176,7 +1195,7 @@ static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize,
11761195
11771196 // i/j/k
11781197 (*token)++; // skip '/'
1179- if (!fixIndex (atoi ((*token)), vnsize, &( vi.vn_idx ) )) {
1198+ if (!fixIndex (atoi ((*token)), vnsize, &vi.vn_idx , true , context )) {
11801199 return false ;
11811200 }
11821201 (*token) += strcspn ((*token), " / \t\r " );
@@ -1419,7 +1438,7 @@ inline real_t GetLength(TinyObjPoint &e) {
14191438}
14201439
14211440inline TinyObjPoint Normalize (TinyObjPoint e) {
1422- real_t inv_length = 1.0 / GetLength (e);
1441+ real_t inv_length = real_t ( 1 ) / GetLength (e);
14231442 return TinyObjPoint (e.x * inv_length, e.y * inv_length, e.z * inv_length );
14241443}
14251444
@@ -2678,6 +2697,10 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
26782697 vw.push_back (sw);
26792698 }
26802699
2700+ warning_context context;
2701+ context.warn = warn;
2702+ context.line_number = line_num;
2703+
26812704 // line
26822705 if (token[0 ] == ' l' && IS_SPACE ((token[1 ]))) {
26832706 token += 2 ;
@@ -2688,13 +2711,10 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
26882711 vertex_index_t vi;
26892712 if (!parseTriple (&token, static_cast <int >(v.size () / 3 ),
26902713 static_cast <int >(vn.size () / 3 ),
2691- static_cast <int >(vt.size () / 2 ), &vi)) {
2714+ static_cast <int >(vt.size () / 2 ), &vi, context )) {
26922715 if (err) {
2693- std::stringstream ss;
2694- ss << " Failed parse `l' line(e.g. zero value for vertex index. "
2695- " line "
2696- << line_num << " .)\n " ;
2697- (*err) += ss.str ();
2716+ (*err) += " Failed to parse `l' line (e.g. a zero value for vertex index. Line " +
2717+ toString (line_num) + " ).\n " ;
26982718 }
26992719 return false ;
27002720 }
@@ -2720,13 +2740,10 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
27202740 vertex_index_t vi;
27212741 if (!parseTriple (&token, static_cast <int >(v.size () / 3 ),
27222742 static_cast <int >(vn.size () / 3 ),
2723- static_cast <int >(vt.size () / 2 ), &vi)) {
2743+ static_cast <int >(vt.size () / 2 ), &vi, context )) {
27242744 if (err) {
2725- std::stringstream ss;
2726- ss << " Failed parse `p' line(e.g. zero value for vertex index. "
2727- " line "
2728- << line_num << " .)\n " ;
2729- (*err) += ss.str ();
2745+ (*err) += " Failed to parse `p' line (e.g. a zero value for vertex index. Line " +
2746+ toString (line_num) + " ).\n " ;
27302747 }
27312748 return false ;
27322749 }
@@ -2756,12 +2773,10 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
27562773 vertex_index_t vi;
27572774 if (!parseTriple (&token, static_cast <int >(v.size () / 3 ),
27582775 static_cast <int >(vn.size () / 3 ),
2759- static_cast <int >(vt.size () / 2 ), &vi)) {
2776+ static_cast <int >(vt.size () / 2 ), &vi, context )) {
27602777 if (err) {
2761- std::stringstream ss;
2762- ss << " Failed parse `f' line(e.g. zero value for face index. line "
2763- << line_num << " .)\n " ;
2764- (*err) += ss.str ();
2778+ (*err) += " Failed to parse `f' line (e.g. a zero value for vertex index. Line " +
2779+ toString (line_num) + " ).\n " ;
27652780 }
27662781 return false ;
27672782 }
0 commit comments