Add model.xml fallback search path to mjz decoder

PiperOrigin-RevId: 949690037
Change-Id: I93978c1f9ded12c69ffe321fe1f85721db32f555
This commit is contained in:
Sam Haves
2026-07-17 12:02:03 -07:00
committed by Copybara-Service
parent e3293a5f29
commit ebd4abae03
2 changed files with 24 additions and 10 deletions
+1
View File
@@ -72,6 +72,7 @@ General
integrator and flex stiffness present; Newton and PGS are unaffected. Bending-only models pay zero per-step
factorization cost (the factor is precomputed in :ref:`mj_setConst<mj_setConst>`). Inverse dynamics
(:ref:`mj_inverse<mj_inverse>`) is now discrete-consistent with forward dynamics for gated models.
- The ``mjz`` decoder now searches for ``model.xml`` at the root of the archive as a fallback if the archive-named XML is not found.
.. admonition:: Breaking API changes
:class: attention
+23 -10
View File
@@ -87,20 +87,33 @@ class ZipArchiveProvider : public mjpResourceProvider {
files_[stat.m_filename] = FileInfo{i, size, {}};
}
// Look for the root XML model in the archive. First look for an XML file
// with the same name as the archive itself. Failing that, look for an XML
// file within a subdirectory with the same name as the archive.
// Look for the root XML model in the archive. We try the following
// locations:
// 1. [archive_name].xml at the root of the archive.
// 2. [archive_name]/[archive_name].xml inside a subdirectory.
// 3. model.xml at the root of the archive (common zipped MJCF pattern).
const std::filesystem::path path(name_);
root_model_ = (path / path.stem()).generic_string() + ".xml";
if (!Contains(root_model_)) {
root_model_ =
(path / path.stem() / path.stem()).generic_string() + ".xml";
if (!Contains(root_model_)) {
SetError(error, error_sz, "Zip error: no root XML file found.");
return;
const std::string stem = path.stem().string();
std::vector<std::string> candidates = {
(path / stem).generic_string() + ".xml",
(path / stem / stem).generic_string() + ".xml",
(path / "model").generic_string() + ".xml",
};
bool found = false;
for (const auto& candidate : candidates) {
if (Contains(candidate)) {
root_model_ = candidate;
found = true;
break;
}
}
if (!found) {
SetError(error, error_sz, "Zip error: no root XML file found.");
return;
}
// Setup mjpResourceProvider callbacks.
mount = [](mjResource* resource) {
return 0;