Skip to content

Commit f026a1e

Browse files
authored
Allow normal and tex indices to be zero + fix a warning (#349)
* Allow normal and tex indices to be zero (cherry picked from commit 4428e7e) * Fixed a warning * Fixed constness * Fixed a warning * Fixed the absence of std::to_string() * Fixed a quirky old compiler error * Fixed a c++03 warning
1 parent 5790ebd commit f026a1e

File tree

1 file changed

+40
-25
lines changed

1 file changed

+40
-25
lines changed

tiny_obj_loader.h

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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
11361155
static 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

14211440
inline 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

Comments
 (0)