From b1eee579fd7243143b3d4740db260a69b40a7094 Mon Sep 17 00:00:00 2001 From: andrijazz Date: Wed, 23 Sep 2020 12:10:53 -0700 Subject: [PATCH] resouces filenames with spaces (#358) Summary: I'm constantly encountering 3D models with resources that have spaces in their filenames (especially on Windows) and therefore they can't be loaded in pytorch3d. Let me know what you think. Thanks Pull Request resolved: https://github.com/facebookresearch/pytorch3d/pull/358 Reviewed By: bottler Differential Revision: D23798492 Pulled By: nikhilaravi fbshipit-source-id: 4d85b7ee05339486d2e5ef53a531f8e6052251c5 --- pytorch3d/io/mtl_io.py | 4 +++- tests/test_obj_io.py | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/pytorch3d/io/mtl_io.py b/pytorch3d/io/mtl_io.py index 32bcc788..5b5ec940 100644 --- a/pytorch3d/io/mtl_io.py +++ b/pytorch3d/io/mtl_io.py @@ -399,7 +399,9 @@ def _parse_mtl(f, device="cpu") -> Tuple[MaterialProperties, TextureFiles]: material_properties[material_name] = {} elif tokens[0] == "map_Kd": # Diffuse texture map - texture_files[material_name] = tokens[1] + # Account for the case where filenames might have spaces + filename = line.strip()[7:] + texture_files[material_name] = filename elif tokens[0] == "Kd": # RGB diffuse reflectivity kd = np.array(tokens[1:4]).astype(np.float32) diff --git a/tests/test_obj_io.py b/tests/test_obj_io.py index f609556a..b8a26b2b 100644 --- a/tests/test_obj_io.py +++ b/tests/test_obj_io.py @@ -12,6 +12,7 @@ from pytorch3d.io import load_obj, load_objs_as_meshes, save_obj from pytorch3d.io.mtl_io import ( _bilinear_interpolation_grid_sample, _bilinear_interpolation_vectorized, + _parse_mtl, ) from pytorch3d.renderer import TexturesAtlas, TexturesUV, TexturesVertex from pytorch3d.structures import Meshes, join_meshes_as_batch @@ -442,6 +443,51 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase): torch.allclose(materials[n1][k1], expected_materials[n2][k2]) ) + def test_load_mtl_with_spaces_in_resource_filename(self): + """ + Check that the texture image for materials in mtl files + is loaded correctly even if there is a space in the file name + e.g. material 1.png + """ + mtl_file = "\n".join( + [ + "newmtl material_1", + "map_Kd material 1.png", + "Ka 1.000 1.000 1.000", # white + "Kd 1.000 1.000 1.000", # white + "Ks 0.000 0.000 0.000", # black + "Ns 10.0", + ] + ) + mtl_file = StringIO(mtl_file) + material_properties, texture_files = _parse_mtl(mtl_file, device="cpu") + + dtype = torch.float32 + expected_materials = { + "material_1": { + "ambient_color": torch.tensor([1.0, 1.0, 1.0], dtype=dtype), + "diffuse_color": torch.tensor([1.0, 1.0, 1.0], dtype=dtype), + "specular_color": torch.tensor([0.0, 0.0, 0.0], dtype=dtype), + "shininess": torch.tensor([10.0], dtype=dtype), + } + } + # Check that there is a material with name material_1 + self.assertTrue(tuple(texture_files.keys()) == ("material_1",)) + # Check that there is an image with name material 1.png + self.assertTrue(texture_files["material_1"] == "material 1.png") + + # Check all keys and values in dictionary are the same. + for n1, n2 in zip(material_properties.keys(), expected_materials.keys()): + self.assertTrue(n1 == n2) + for k1, k2 in zip( + material_properties[n1].keys(), expected_materials[n2].keys() + ): + self.assertTrue( + torch.allclose( + material_properties[n1][k1], expected_materials[n2][k2] + ) + ) + def test_load_mtl_texture_atlas_compare_softras(self): # Load saved texture atlas created with SoftRas. device = torch.device("cuda:0")