#mjspec Enforce that material textures array is always of length mjNTEXROLE.

PiperOrigin-RevId: 855684213
Change-Id: Id8a3734c75841dfb91bd2252114249f08461b7f2
This commit is contained in:
Google DeepMind
2026-01-13 05:54:06 -08:00
committed by Copybara-Service
parent a93db89d43
commit 09a6fb7d4d
2 changed files with 50 additions and 5 deletions
@@ -239,6 +239,30 @@ def _ptr_binding_code(
}}
}}, py::return_value_policy::move);"""
elif vartype == 'mjStringVec':
# Special case for material.textures: must be exactly mjNTEXROLE size
if classname == 'mjsMaterial' and varname == 'textures':
return f"""\
{classname}.def_property(
"{varname}",
[]({rawclassname}& self) -> MjTypeVec<std::string> {{
return MjTypeVec<std::string>(self.{fullvarname}->data(),
self.{fullvarname}->size());
}},
[]({rawclassname}& self, py::object rhs) {{
if (py::len(rhs) != mjNTEXROLE) {{
throw pybind11::value_error(
"material.textures must have exactly " + std::to_string(mjNTEXROLE) +
" elements, got " + std::to_string(py::len(rhs)) + ". " +
"Assign a list of " + std::to_string(mjNTEXROLE) + " texture names " +
"(use empty strings '' for unused slots).");
}}
self.{fullvarname}->clear();
self.{fullvarname}->reserve(mjNTEXROLE);
for (auto val : rhs) {{
self.{fullvarname}->push_back(py::cast<std::string>(val));
}}
}}, py::return_value_policy::move);"""
# Default case for other mjStringVec properties
return f"""\
{classname}.def_property(
"{varname}",