Skip to content

Commit 8d3cde9

Browse files
Adrian Collistercopybara-github
authored andcommitted
Allow full model-relative paths to be used as keys in asset dicts.
Allowing keys in this form means the asset dict can be constructed without needing to first parse the XML to determine whether any special directories have been specified in the compiler options. For example, given an asset in `assets/textures/texture.png` and an `assetdir` set to "assets", this asset previously had to be keyed in the assets dict by "textures/texture.png". After this CL, it's also permitted to use "assets/textures/texture.png". PiperOrigin-RevId: 807216952 Change-Id: Ie1b8680eec447562675e4ca83aa15b1c4511461e
1 parent f3f5bad commit 8d3cde9

File tree

2 files changed

+31
-25
lines changed

2 files changed

+31
-25
lines changed

dm_control/mjcf/attribute.py

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -518,39 +518,34 @@ def _get_asset_from_path(self, path):
518518
_, basename = os.path.split(path)
519519
filename, extension = os.path.splitext(basename)
520520

521-
assetdir = None
521+
# Construct the path to the asset file (relative to the model directory),
522+
# prefixed by the appropriate base path, if specified.
523+
base_path = None
522524
if self._parent.namescope.has_identifier(
525+
constants.BASEPATH, self._path_namespace
526+
):
527+
base_path = self._parent.namescope.get(
528+
constants.BASEPATH, self._path_namespace
529+
)
530+
elif self._path_namespace in (
531+
constants.TEXTUREDIR_NAMESPACE,
532+
constants.MESHDIR_NAMESPACE,
533+
) and self._parent.namescope.has_identifier(
523534
constants.BASEPATH, constants.ASSETDIR_NAMESPACE
524535
):
525-
assetdir = self._parent.namescope.get(
536+
base_path = self._parent.namescope.get(
526537
constants.BASEPATH, constants.ASSETDIR_NAMESPACE
527538
)
539+
full_path = os.path.join(base_path, path) if base_path else path
528540

541+
# Look in the dict of pre-loaded assets before checking the filesystem.
529542
if path in self._parent.namescope.assets:
530-
# Look in the dict of pre-loaded assets before checking the filesystem.
531543
contents = self._parent.namescope.assets[path]
544+
elif full_path in self._parent.namescope.assets:
545+
contents = self._parent.namescope.assets[full_path]
532546
else:
533-
# Construct the full path to the asset file, prefixed by the path to the
534-
# model directory, and by `meshdir` or `texturedir` if appropriate.
535-
path_parts = []
536547
if self._parent.namescope.model_dir:
537-
path_parts.append(self._parent.namescope.model_dir)
538-
539-
if self._parent.namescope.has_identifier(
540-
constants.BASEPATH, self._path_namespace
541-
):
542-
base_path = self._parent.namescope.get(
543-
constants.BASEPATH, self._path_namespace
544-
)
545-
path_parts.append(base_path)
546-
elif (
547-
self._path_namespace
548-
in (constants.TEXTUREDIR_NAMESPACE, constants.MESHDIR_NAMESPACE)
549-
and assetdir is not None
550-
):
551-
path_parts.append(assetdir)
552-
path_parts.append(path)
553-
full_path = os.path.join(*path_parts) # pylint: disable=no-value-for-parameter
548+
full_path = os.path.join(self._parent.namescope.model_dir, full_path)
554549
contents = resources.GetResource(full_path)
555550

556551
if self._parent.tag == constants.SKIN:

dm_control/mjcf/attribute_test.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
# limitations under the License.
1414
# ============================================================================
1515

16-
"""Tests for `dm_control.mjcf.attribute`."""
17-
1816
import contextlib
1917
import hashlib
2018
import os
@@ -455,6 +453,19 @@ def testFileFromAssetsDict(self):
455453
contents=contents, extension=extension, prefix=prefix)
456454
self.assertEqual(text_file.file, expected_value)
457455

456+
def testFileFromAssetsDictWithBasepath(self):
457+
prefix = 'fake_filename'
458+
extension = '.whatever'
459+
path = 'invalid/path/' + prefix + extension
460+
contents = 'Fake contents'
461+
assets = {os.path.join(ASSETS_DIR, path): contents}
462+
mujoco = element.RootElement(assets=assets)
463+
mujoco.files.text_path = ASSETS_DIR
464+
text_file = mujoco.files.add('text', file=path)
465+
expected_value = attribute.Asset(
466+
contents=contents, extension=extension, prefix=prefix)
467+
self.assertEqual(text_file.file, expected_value)
468+
458469
def testFileExceptions(self):
459470
mujoco = self._mujoco
460471
text_file = mujoco.files.add('text')

0 commit comments

Comments
 (0)