Skip to content

Fix #3104: include file-referenced assets in MjSpec.to_zip#3372

Open
Ashutosh0x wants to merge 1 commit into
google-deepmind:mainfrom
Ashutosh0x:fix/issue-3104
Open

Fix #3104: include file-referenced assets in MjSpec.to_zip#3372
Ashutosh0x wants to merge 1 commit into
google-deepmind:mainfrom
Ashutosh0x:fix/issue-3104

Conversation

@Ashutosh0x

Copy link
Copy Markdown
Contributor

Problem

MjSpec.to_zip only serializes assets present in the Python-side spec.assets dict. Assets referenced via XML file attributes — e.g. <mesh file="cube.obj"/>, <texture file="tex.png"/> — are loaded by the C layer from disk but are never added to spec.assets, so they are silently omitted from the zip. The resulting zip cannot be reloaded.

Fixes #3104.

Changes

python/mujoco/__init__.py

  • After copying spec.assets, walk all spec elements that can carry file references: meshes, hfields, skins, and textures (including cubefiles).
  • For each referenced file not already present in the dict, resolve the path against spec.modelfiledir and read it from disk. Files not found on disk are silently skipped (in-memory assets already in spec.assets take precedence).
  • Two secondary bugs also fixed:
    • spec.assets was mutated in-place (files_to_zip = spec.assets then items were added to it); now a copy is made first so the caller's dict is untouched.
    • os.makedirs(directory, ...) was called even when directory is '' (e.g. saving to current directory), which raises FileNotFoundError; now guarded with if directory.

python/mujoco/specs_test.py

  • test_to_zip_includes_file_assets: loads testdata/msh.xml (which references abdomen_1_body.msh by file path), calls to_zip, and asserts the mesh file is present in the zip. Also verifies the zip round-trips to a compilable spec.
  • test_to_zip_does_not_mutate_assets: asserts spec.assets content is unchanged after to_zip.

Reproducer

import io
import mujoco

spec = mujoco.MjSpec.from_file("model_with_mesh.xml")
buf = io.BytesIO()
mujoco.to_zip(spec, buf)
buf.seek(0)
spec2 = mujoco.from_zip(buf)
model = spec2.compile()  # previously raised -- now works

…_zip

to_zip only serialized assets present in spec.assets (the Python-side
dict). Assets referenced via XML file paths, e.g. <mesh file=cube.obj/>,
were loaded by the C layer but never added to spec.assets, so they
were silently omitted from the zip, making it unloadable.

Fix: walk all spec elements that can carry file references (meshes,
hfields, skins, textures including cubefiles) and read each referenced
file from disk when it is not already in spec.assets. Also fix two
secondary bugs: spec.assets was mutated in-place (now copied first),
and os.makedirs was called with an empty string when saving to the
current directory (now guarded).

Fixes google-deepmind#3104
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assets missing from MjSpec.to_zip

1 participant