Skip to content

Commit 0171fe8

Browse files
committed
Fix to_zip for referenced files
1 parent 7519346 commit 0171fe8

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed

python/mujoco/__init__.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,30 +108,42 @@ def to_zip(spec: _specs.MjSpec, file: Union[str, IO[bytes]]) -> None:
108108
"""
109109
files_to_zip = spec.assets
110110

111-
def _add_files(elements):
112-
for element in elements:
113-
if element.file in files_to_zip:
114-
# TODO(hartikainen): What should we do in this case?
115-
raise ValueError(f'Asset file {element.file} is already included in the zip file.')
111+
strip_path = bool(spec.strippath)
112+
model_dir = spec.modelfiledir
113+
114+
def _resolve_path(filename: str, compiler_dir: str) -> Path:
115+
if strip_path:
116+
filename = os.path.basename(filename)
117+
118+
path = Path(filename)
116119

117-
file = Path(element.file)
120+
if path.is_absolute():
121+
return path
118122

119-
if not file.exists():
120-
raise FileNotFoundError(f'Asset file {element.file} not found.')
121-
if not file.is_file():
122-
raise ValueError(f'Asset file {element.file} is not a file.')
123+
if compiler_dir and Path(compiler_dir).is_absolute():
124+
return Path(compiler_dir) / path
123125

124-
files_to_zip[element.file] = file.read_bytes()
126+
base_dir = Path(model_dir) if model_dir else Path.cwd()
127+
if compiler_dir:
128+
return base_dir / compiler_dir / path
129+
130+
return base_dir / path
131+
132+
def _add_files(elements, compiler_dir: str):
133+
for element in elements:
134+
if element.file and element.file not in files_to_zip:
135+
file_path = _resolve_path(element.file, compiler_dir)
136+
if file_path.exists():
137+
files_to_zip[element.file] = file_path.read_bytes()
125138

126-
_add_files(spec.meshes)
127-
_add_files(spec.textures)
128-
_add_files(spec.skins)
129-
_add_files(spec.hfields)
139+
_add_files(spec.meshes, spec.compiler.meshdir)
140+
_add_files(spec.textures, spec.compiler.texturedir)
141+
_add_files(spec.skins, spec.compiler.meshdir)
142+
_add_files(spec.hfields, spec.compiler.meshdir)
130143

131144
files_to_zip[spec.modelname + '.xml'] = spec.to_xml()
132145
if isinstance(file, str):
133-
file = Path(file)
134-
file.parent.mkdir(parents=True, exist_ok=True)
146+
Path(file).parent.mkdir(parents=True, exist_ok=True)
135147
with zipfile.ZipFile(file, 'w') as zip_file:
136148
for filename, contents in files_to_zip.items():
137149
zip_info = zipfile.ZipInfo(filename)

python/mujoco/specs_test.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import inspect
1919
import math
2020
import os
21+
from pathlib import Path
2122
import textwrap
2223
import typing
2324
import zipfile # pylint: disable=unused-import
@@ -1781,9 +1782,21 @@ def test_to_zip_includes_assets(self):
17811782
self.assertEqual(z.read(texture_filename), f.read())
17821783
self.assertIn('test_model.xml', z.namelist())
17831784

1785+
spec1 = mujoco.MjSpec.from_zip(zip_filename)
1786+
model = spec1.compile()
1787+
17841788
def test_to_zip_includes_assets_from_references(self):
1785-
spec = mujoco.MjSpec.from_file("test/user/testdata/cube.xml")
1786-
spec.to_zip("/tmp/cube.zip")
1789+
temp_dir = self.create_tempdir()
1790+
temp_dir_path = epath.Path(temp_dir.full_path)
1791+
1792+
zip_path = temp_dir_path / "cube.zip"
1793+
mesh_model_path = epath.resource_path("mujoco") / "testdata" / "msh.xml"
1794+
1795+
spec0 = mujoco.MjSpec.from_file(mesh_model_path.as_posix())
1796+
spec0.to_zip(zip_path.as_posix())
1797+
1798+
spec1 = mujoco.MjSpec.from_zip(zip_path.as_posix())
1799+
model = spec1.compile()
17871800

17881801
def test_rangefinder_sensor(self):
17891802
"""Test rangefinder sensor with mjSpec, iterative model building."""

0 commit comments

Comments
 (0)