[Bf-blender-cvs] [50f9c1c09ce] master: OBJ: more robust .mtl texture offset/scale parsing (T89421)

Aras Pranckevicius noreply at git.blender.org
Thu Jul 7 10:35:06 CEST 2022


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));



More information about the Bf-blender-cvs mailing list