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
This commit is contained in:
andrijazz 2020-09-23 12:10:53 -07:00 committed by Facebook GitHub Bot
parent 93d3d8feda
commit b1eee579fd
2 changed files with 49 additions and 1 deletions

View File

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

View File

@ -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")