diff options
author | Louise Poubel <louise@openrobotics.org> | 2020-11-17 14:31:19 -0800 |
---|---|---|
committer | Louise Poubel <louise@openrobotics.org> | 2020-11-17 14:31:19 -0800 |
commit | b46cd4685edb126dc1cd754dc61b247e5e773d0d (patch) | |
tree | 022f4667d5023f2ffb7b869d02dc61a978f164a4 | |
parent | a40e9c2fa2b592993005a94d432a37601c5390db (diff) | |
download | tinyobjloader-b46cd4685edb126dc1cd754dc61b247e5e773d0d.tar.gz |
Support MTL files with escaped whitespace
Signed-off-by: Louise Poubel <louise@openrobotics.org>
-rw-r--r-- | examples/viewer/README.md | 2 | ||||
-rw-r--r-- | models/mtl filename with whitespace issue46.mtl | 4 | ||||
-rw-r--r-- | models/mtl filename with whitespace issue46.obj | 31 | ||||
-rw-r--r-- | tests/tester.cc | 26 | ||||
-rw-r--r-- | tiny_obj_loader.h | 34 |
5 files changed, 87 insertions, 10 deletions
diff --git a/examples/viewer/README.md b/examples/viewer/README.md index 83392f0..76207bf 100644 --- a/examples/viewer/README.md +++ b/examples/viewer/README.md @@ -5,6 +5,8 @@ * premake5 * glfw3 * glew +* xcursor +* xinerama ## Build on MaCOSX diff --git a/models/mtl filename with whitespace issue46.mtl b/models/mtl filename with whitespace issue46.mtl new file mode 100644 index 0000000..b79d99b --- /dev/null +++ b/models/mtl filename with whitespace issue46.mtl @@ -0,0 +1,4 @@ +newmtl green +Ka 0 0 0 +Kd 0 1 0 +Ks 0 0 0 diff --git a/models/mtl filename with whitespace issue46.obj b/models/mtl filename with whitespace issue46.obj new file mode 100644 index 0000000..72d1dc9 --- /dev/null +++ b/models/mtl filename with whitespace issue46.obj @@ -0,0 +1,31 @@ +mtllib invalid-file-without-spaces.mtl invalid\ file\ with\ spaces.mtl mtl\ filename\ with\ whitespace\ issue46.mtl + +v 0.000000 2.000000 2.000000 +v 0.000000 0.000000 2.000000 +v 2.000000 0.000000 2.000000 +v 2.000000 2.000000 2.000000 +v 0.000000 2.000000 0.000000 +v 0.000000 0.000000 0.000000 +v 2.000000 0.000000 0.000000 +v 2.000000 2.000000 0.000000 +# 8 vertices + +g front cube +usemtl green +f 1 2 3 4 +g back cube +usemtl green +f 8 7 6 5 +g right cube +usemtl green +f 4 3 7 8 +g left cube +usemtl green +f 5 6 2 1 +g top cube +usemtl green +f 5 1 4 8 +g bottom cube +usemtl green +f 2 6 7 3 +# 6 elements diff --git a/tests/tester.cc b/tests/tester.cc index 7538c74..0fd0dbc 100644 --- a/tests/tester.cc +++ b/tests/tester.cc @@ -1308,6 +1308,30 @@ void test_texres_texopt_issue248() { TEST_CHECK("input.jpg" == materials[0].diffuse_texname); } +void test_mtl_filename_with_whitespace_issue46() { + tinyobj::attrib_t attrib; + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> materials; + + std::string warn; + std::string err; + bool ret = + tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, + "../models/mtl filename with whitespace issue46.obj", + gMtlBasePath); + + if (!warn.empty()) { + std::cout << "WARN: " << warn << std::endl; + } + + if (!err.empty()) { + std::cerr << "ERR: " << err << std::endl; + } + TEST_CHECK(true == ret); + TEST_CHECK(1 == materials.size()); + TEST_CHECK("green" == materials[0].name); +} + // Fuzzer test. // Just check if it does not crash. // Disable by default since Windows filesystem can't create filename of afl @@ -1407,4 +1431,6 @@ TEST_LIST = { test_usemtl_whitespace_issue246}, {"texres_texopt_issue248", test_texres_texopt_issue248}, + {"test_mtl_filename_with_whitespace_issue46", + test_mtl_filename_with_whitespace_issue46}, {NULL, NULL}}; diff --git a/tiny_obj_loader.h b/tiny_obj_loader.h index edd18f5..c848959 100644 --- a/tiny_obj_loader.h +++ b/tiny_obj_loader.h @@ -1658,16 +1658,30 @@ static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group, return true; } -// Split a string with specified delimiter character. -// http://stackoverflow.com/questions/236129/split-a-string-in-c -static void SplitString(const std::string &s, char delim, +// Split a string with specified delimiter character and escape character. +// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B +static void SplitString(const std::string &s, char delim, char escape, std::vector<std::string> &elems) { - std::stringstream ss; - ss.str(s); - std::string item; - while (std::getline(ss, item, delim)) { - elems.push_back(item); + std::string token; + + bool escaping = false; + for (char ch : s) { + if (escaping) { + escaping = false; + } else if (ch == escape) { + escaping = true; + continue; + } else if (ch == delim) { + if (!token.empty()) { + elems.push_back(token); + } + token.clear(); + continue; + } + token += ch; } + + elems.push_back(token); } static std::string JoinPath(const std::string &dir, @@ -2483,7 +2497,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes, token += 7; std::vector<std::string> filenames; - SplitString(std::string(token), ' ', filenames); + SplitString(std::string(token), ' ', '\\', filenames); if (filenames.empty()) { if (warn) { @@ -2891,7 +2905,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, token += 7; std::vector<std::string> filenames; - SplitString(std::string(token), ' ', filenames); + SplitString(std::string(token), ' ', '\\', filenames); if (filenames.empty()) { if (warn) { |