Commit: 50f9c1c09ce331c7ce09115016ba3e4407691701 Author: Aras Pranckevicius Date: Thu Jul 7 11:34:04 2022 +0300 Branches: master https://developer.blender.org/rB50f9c1c09ce331c7ce09115016ba3e4407691701
OBJ: more robust .mtl texture offset/scale parsing (T89421) As pointed out in a comment on T89421, if a MTL file contained something like: `map_Ka -o 1 2.png` then it was parsed as having offset `1 2` and the texture filename just a `.png`. Make it so that mtl option numbers are parsed in a way where the number is only accepted only if it's followed by whitespace. Differential Revision: https://developer.blender.org/D15385 =================================================================== M source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc M source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc M source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh M source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc M source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc =================================================================== diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index 3cc17e7d8e6..c2aa96713b1 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -626,15 +626,15 @@ static bool parse_texture_option(const char *&p, { p = drop_whitespace(p, end); if (parse_keyword(p, end, "-o")) { - p = parse_floats(p, end, 0.0f, tex_map.translation, 3); + p = parse_floats(p, end, 0.0f, tex_map.translation, 3, true); return true; } if (parse_keyword(p, end, "-s")) { - p = parse_floats(p, end, 1.0f, tex_map.scale, 3); + p = parse_floats(p, end, 1.0f, tex_map.scale, 3, true); return true; } if (parse_keyword(p, end, "-bm")) { - p = parse_float(p, end, 1.0f, material->map_Bump_strength); + p = parse_float(p, end, 1.0f, material->map_Bump_strength, true, true); return true; } if (parse_keyword(p, end, "-type")) { diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc index c8eaa046e68..bc9006e1051 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc @@ -62,8 +62,12 @@ static const char *drop_plus(const char *p, const char *end) return p; } -const char *parse_float( - const char *p, const char *end, float fallback, float &dst, bool skip_space) +const char *parse_float(const char *p, + const char *end, + float fallback, + float &dst, + bool skip_space, + bool require_trailing_space) { if (skip_space) { p = drop_whitespace(p, end); @@ -73,13 +77,23 @@ const char *parse_float( if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) { dst = fallback; } + else if (require_trailing_space && res.ptr < end && !is_whitespace(*res.ptr)) { + /* If there are trailing non-space characters, do not eat up the number. */ + dst = fallback; + return p; + } return res.ptr; } -const char *parse_floats(const char *p, const char *end, float fallback, float *dst, int count) +const char *parse_floats(const char *p, + const char *end, + float fallback, + float *dst, + int count, + bool require_trailing_space) { for (int i = 0; i < count; ++i) { - p = parse_float(p, end, fallback, dst[i]); + p = parse_float(p, end, fallback, dst[i], true, require_trailing_space); } return p; } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh index 3f428b1ab5c..f6dd1a6b675 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh @@ -62,12 +62,17 @@ const char *parse_int( * The parsed result is stored in `dst`. The function skips * leading white-space unless `skip_space=false`. If the * number can't be parsed (invalid syntax, out of range), - * `fallback` value is stored instead. + * `fallback` value is stored instead. If `require_trailing_space` + * is true, the character after the number has to be whitespace. * * Returns the start of remainder of the input string after parsing. */ -const char *parse_float( - const char *p, const char *end, float fallback, float &dst, bool skip_space = true); +const char *parse_float(const char *p, + const char *end, + float fallback, + float &dst, + bool skip_space = true, + bool require_trailing_space = false); /** * Parse a number of white-space separated floats from an input string. @@ -77,6 +82,11 @@ const char *parse_float( * * Returns the start of remainder of the input string after parsing. */ -const char *parse_floats(const char *p, const char *end, float fallback, float *dst, int count); +const char *parse_floats(const char *p, + const char *end, + float fallback, + float *dst, + int count, + bool require_trailing_space = false); } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc b/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc index 46e093bb8a7..e9747b437cc 100644 --- a/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc @@ -29,9 +29,14 @@ static StringRef parse_int(StringRef s, int fallback, int &dst, bool skip_space { return StringRef(parse_int(s.begin(), s.end(), fallback, dst, skip_space), s.end()); } -static StringRef parse_float(StringRef s, float fallback, float &dst, bool skip_space = true) +static StringRef parse_float(StringRef s, + float fallback, + float &dst, + bool skip_space = true, + bool require_trailing_space = false) { - return StringRef(parse_float(s.begin(), s.end(), fallback, dst, skip_space), s.end()); + return StringRef( + parse_float(s.begin(), s.end(), fallback, dst, skip_space, require_trailing_space), s.end()); } TEST(obj_import_string_utils, drop_whitespace) @@ -126,6 +131,9 @@ TEST(obj_import_string_utils, parse_float_invalid) /* Has leading white-space when we don't expect it */ EXPECT_STRREF_EQ(" 1", parse_float(" 1", -4.0f, val, false)); EXPECT_EQ(val, -4.0f); + /* Has trailing non-number characters when we don't want them */ + EXPECT_STRREF_EQ("123.5.png", parse_float(" 123.5.png", -5.0f, val, true, true)); + EXPECT_EQ(val, -5.0f); } } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc index 5b909865d9b..08050ac34c9 100644 --- a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc @@ -247,7 +247,7 @@ TEST_F(obj_mtl_parser_test, materials) ks.image_path = "ScaleOffsetBothTwovalues.png"; tex_map_XX &ns = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ns); ns.scale = {0.5f, 1.0f, 1.0f}; - ns.image_path = "ScaleOneValue.png"; + ns.image_path = "1.Value.png"; } check("materials.mtl", mat, ARRAY_SIZE(mat)); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs