From 1a4ddca6cfd352fbb9a04bcf53e6e5d485e5b278 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 7 Jul 2025 09:50:49 -0700 Subject: [PATCH] Make mjs_findElement find meshes by file name. PiperOrigin-RevId: 780150428 Change-Id: Ie500062fa8cca755683b66540e84ede588d7c331 --- python/mujoco/specs_test.py | 7 ++++++- src/user/user_api.cc | 4 +++- src/user/user_model.cc | 20 +++++++++++++------- src/user/user_model.h | 5 ++++- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/python/mujoco/specs_test.py b/python/mujoco/specs_test.py index 65d2897f..d24b6cea 100644 --- a/python/mujoco/specs_test.py +++ b/python/mujoco/specs_test.py @@ -984,13 +984,18 @@ class SpecsTest(absltest.TestCase): texture.data = np.zeros((2, 2, 3), dtype=np.uint8).tobytes() spec.compile() - def test_find_unnamed_texture(self): + def test_find_unnamed_asset(self): spec = mujoco.MjSpec() texture_file = spec.add_texture(file='file.png') texture_name = spec.add_texture(name='name') + mesh_file = spec.add_mesh(file='file.obj') + mesh_name = spec.add_mesh(name='mesh') self.assertEqual(spec.texture('file'), texture_file) self.assertEqual(spec.texture('name'), texture_name) + self.assertEqual(spec.mesh('file'), mesh_file) + self.assertEqual(spec.mesh('mesh'), mesh_name) self.assertIsNone(spec.texture('none')) + self.assertIsNone(spec.mesh('none')) def test_attach_units(self): child = mujoco.MjSpec() diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 4fcc9c1a..95280bbd 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -910,7 +910,9 @@ mjsElement* mjs_findElement(mjSpec* s, mjtObj type, const char* name) { case mjOBJ_FRAME: return model->FindTree(model->GetWorld(), type, std::string(name)); // recursive search case mjOBJ_TEXTURE: - return model->FindTexture(std::string(name)); // check filename too + return model->FindAsset(std::string(name), model->Textures()); // check filename too + case mjOBJ_MESH: + return model->FindAsset(std::string(name), model->Meshes()); // check filename too default: return model->FindObject(type, std::string(name)); // always available } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 7b671ed5..a1b358ac 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -1338,19 +1338,25 @@ static T* findobject(std::string_view name, const vector& list, const mjKeyM -mjCBase* mjCModel::FindTexture(std::string_view name) const { - for (unsigned int i=0; i < textures_.size(); i++) { - if (textures_[i]->name == name) { - return textures_[i]; +template +mjCBase* mjCModel::FindAsset(std::string_view name, const std::vector& list) const { + for (unsigned int i=0; i < list.size(); i++) { + if (list[i]->name == name) { + return list[i]; } - if (textures_[i]->name.empty() && - std::filesystem::path(textures_[i]->spec_file_).filename().stem() == name) { - return textures_[i]; + if (list[i]->name.empty() && + std::filesystem::path(list[i]->spec_file_).filename().stem() == name) { + return list[i]; } } return nullptr; } +template mjCBase* mjCModel::FindAsset( + std::string_view name, const std::vector& list) const; +template mjCBase* mjCModel::FindAsset( + std::string_view name, const std::vector& list) const; + // find object in global lists given string type and name diff --git a/src/user/user_model.h b/src/user/user_model.h index 288446ec..0c229e71 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -246,12 +246,15 @@ class mjCModel : public mjCModel_, private mjSpec { mjCDef* FindDefault(std::string name); // find defaults class name mjCDef* AddDefault(std::string name, mjCDef* parent = nullptr); // add defaults class to array mjCBase* FindObject(mjtObj type, std::string name) const; // find object given type and name - mjCBase* FindTexture(std::string_view name) const; // find texture given name mjCBase* FindTree(mjCBody* body, mjtObj type, std::string name); // find tree object given name mjSpec* FindSpec(std::string name) const; // find spec given name mjSpec* FindSpec(const mjsCompiler* compiler_); // find spec given mjsCompiler void ActivatePlugin(const mjpPlugin* plugin, int slot); // activate plugin + // find asset given name checking both name and filename + template + mjCBase* FindAsset(std::string_view name, const std::vector& list) const; + // accessors std::string get_meshdir() const { return meshdir_; } std::string get_texturedir() const { return texturedir_; }