From afd32b593cd39e5035d33e70e1d200eebb698e19 Mon Sep 17 00:00:00 2001 From: Russ Tedrake Date: Tue, 12 Jul 2022 21:23:10 -0400 Subject: [PATCH] [meshcat] More robust parsing of .mtl texture map filenames (#17550) In https://github.com/RobotLocomotion/models/pull/18 (homecart_basecart.mtl) I ran into a texture map specification that specified a scale option in the map_Kd line. This defeated the simple regex expression that I had implemented in meschat.cc. meshcat.cc doesn't need to parse these options properly; it only needs to successfully extract the filename so that the file can be shipped over the websocket. I've updated the parsing line according to the mtl specification to ignore options. To reproduce the problem, run meshcat_manual_test with the change to box.obj.mtl but without the fix to meshcat.cc. You will see that the box appears in meshcat without a texture and a warning from meshcat.cc is printed to the console. The change to meshcat.cc resolves the problem. --- geometry/meshcat.cc | 12 ++++++++++-- geometry/render/test/meshes/box.obj.mtl | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/geometry/meshcat.cc b/geometry/meshcat.cc index 2ff758ca85c0..445140e5a6d2 100644 --- a/geometry/meshcat.cc +++ b/geometry/meshcat.cc @@ -406,8 +406,16 @@ class MeshcatShapeReifier : public ShapeReifier { // Scan .mtl file for map_ lines. For each, load the file and add // the contents to geometry.resources. - // TODO(russt): Make this parsing more robust. - std::regex map_regex("map_[^\\s]+\\s+([^\\s]+)"); + // The syntax (http://paulbourke.net/dataformats/mtl/) is e.g. + // map_Ka -options args filename + // Here we ignore the options and only extract the filename (by + // extracting the last word before the end of line/string). + // - "map_.+" matches the map_ plus any options, + // - "\s" matches one whitespace (before the filename), + // - "[^\s]+" matches the filename, and + // - "[$\r\n]" matches the end of string or end of line. + // TODO(russt): This parsing could still be more robust. + std::regex map_regex(R"""(map_.+\s([^\s]+)[$\r\n])"""); for (std::sregex_iterator iter(meshfile_object.mtl_library.begin(), meshfile_object.mtl_library.end(), map_regex); diff --git a/geometry/render/test/meshes/box.obj.mtl b/geometry/render/test/meshes/box.obj.mtl index 2dae7de296dd..136bebfb177e 100644 --- a/geometry/render/test/meshes/box.obj.mtl +++ b/geometry/render/test/meshes/box.obj.mtl @@ -5,4 +5,4 @@ Ks 1.000000 1.000000 1.000000 d 1.000000 illum 2 Ns 0.000000 -map_Kd box.png +map_Kd -s 1 1 1 box.png