Add MjSpec.from_zip() constructor.
PiperOrigin-RevId: 736871864 Change-Id: Ib6cc189d5912a57e5c505c744a4a1d6ad61d1c84
This commit is contained in:
committed by
Copybara-Service
parent
1a67aaf1b7
commit
f480a9e985
@@ -91,7 +91,7 @@ MjStruct: TypeAlias = Union[
|
|||||||
|
|
||||||
|
|
||||||
def to_zip(spec: _specs.MjSpec, file: Union[str, IO[bytes]]) -> None:
|
def to_zip(spec: _specs.MjSpec, file: Union[str, IO[bytes]]) -> None:
|
||||||
"""Converts a spec to a zip file.
|
"""Converts an MjSpec to a zip file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec: The mjSpec to save to a file.
|
spec: The mjSpec to save to a file.
|
||||||
@@ -109,6 +109,33 @@ def to_zip(spec: _specs.MjSpec, file: Union[str, IO[bytes]]) -> None:
|
|||||||
zip_file.writestr(zip_info, contents)
|
zip_file.writestr(zip_info, contents)
|
||||||
|
|
||||||
|
|
||||||
|
def from_zip(file: Union[str, IO[bytes]]) -> _specs.MjSpec:
|
||||||
|
"""Reads a zip file and returns an MjSpec.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file: The path to the file to read from or the file object to read from.
|
||||||
|
Returns:
|
||||||
|
An MjSpec object.
|
||||||
|
"""
|
||||||
|
assets = {}
|
||||||
|
xml_string = None
|
||||||
|
if isinstance(file, str):
|
||||||
|
file = open(file, 'rb')
|
||||||
|
if not zipfile.is_zipfile(file):
|
||||||
|
raise ValueError(f'File {file} is not a zip file.')
|
||||||
|
with zipfile.ZipFile(file, 'r') as zip_file:
|
||||||
|
for zip_info in zip_file.infolist():
|
||||||
|
if not zip_info.filename.endswith(os.path.sep):
|
||||||
|
with zip_file.open(zip_info.filename) as f:
|
||||||
|
if zip_info.filename.endswith('.xml'):
|
||||||
|
xml_string = f.read()
|
||||||
|
else:
|
||||||
|
assets[zip_info.filename] = f.read()
|
||||||
|
if not xml_string:
|
||||||
|
raise ValueError('No XML file found in zip file.')
|
||||||
|
return _specs.MjSpec.from_string(xml_string, assets=assets)
|
||||||
|
|
||||||
|
|
||||||
class _MjBindModel:
|
class _MjBindModel:
|
||||||
def __init__(self, elements: Sequence[Any]):
|
def __init__(self, elements: Sequence[Any]):
|
||||||
self.elements = elements
|
self.elements = elements
|
||||||
@@ -166,7 +193,7 @@ def _bind_data(
|
|||||||
else:
|
else:
|
||||||
return data.bind_scalar(specs)
|
return data.bind_scalar(specs)
|
||||||
|
|
||||||
|
_specs.MjSpec.from_zip = from_zip
|
||||||
_specs.MjSpec.to_zip = to_zip
|
_specs.MjSpec.to_zip = to_zip
|
||||||
_structs.MjData.bind = _bind_data
|
_structs.MjData.bind = _bind_data
|
||||||
_structs.MjModel.bind = _bind_model
|
_structs.MjModel.bind = _bind_model
|
||||||
|
|||||||
@@ -758,11 +758,14 @@ class SpecsTest(absltest.TestCase):
|
|||||||
|
|
||||||
xml = """
|
xml = """
|
||||||
<mujoco model="test">
|
<mujoco model="test">
|
||||||
|
<compiler angle="radian"/>
|
||||||
|
|
||||||
<asset>
|
<asset>
|
||||||
<mesh name="cube" file="cube.obj"/>
|
<mesh name="cube" file="cube.obj"/>
|
||||||
</asset>
|
</asset>
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<geom mesh="cube"/>
|
<geom type="mesh" mesh="cube"/>
|
||||||
</worldbody>
|
</worldbody>
|
||||||
</mujoco>
|
</mujoco>
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user