Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAras Pranckevicius <aras@nesnausk.org>2022-07-07 11:34:04 +0300
committerAras Pranckevicius <aras@nesnausk.org>2022-07-07 11:34:13 +0300
commit50f9c1c09ce331c7ce09115016ba3e4407691701 (patch)
tree5f4b43be53c173f56036c19e6691b13dc0a86f0e /source/blender/io
parentbddcb89cdaa6d9b36b3e42547a95bff792d37610 (diff)
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
Diffstat (limited to 'source/blender/io')
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc6
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.cc22
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_string_utils.hh18
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_import_string_utils_tests.cc12
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc2
5 files changed, 46 insertions, 14 deletions
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));