Create list_dependencies sample to list all dependencies for an MCJF file.

PiperOrigin-RevId: 814816067
Change-Id: Idc6232e5d1ef1ff0318aeacd0e3d4b4a5a303485
This commit is contained in:
Sam Haves
2025-10-03 13:46:20 -07:00
committed by Copybara-Service
parent 6ae9cc8061
commit e4704cd28b
8 changed files with 97 additions and 29 deletions
+11
View File
@@ -127,6 +127,17 @@ the required size. XML saving automatically compiles the spec before saving.
Save spec to XML file, return 0 on success, -1 otherwise. XML saving requires that the spec first be compiled.
.. _mju_getXMLDependencies:
`mju_getXMLDependencies <#mju_getXMLDependencies>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_getXMLDependencies
Given MJCF filename, fills dependencies with a list of all other asset files it depends on.
The search is recursive, and the list includes the filename itself.
.. _Mainsimulation:
Main simulation
+4
View File
@@ -24,6 +24,10 @@ General
:ref:`visual/rgba/constraint<visual-rgba-constraint>`. For spatial tendons, this visualization aid is active only if
no :ref:`material<tendon-spatial-material>` is set and :ref:`rgba<tendon-spatial-rgba>` is default.
- Added :ref:`mju_getXMLDependencies` for computing a list of unique asset dependencies from an MJCF file.
- Added the code sample ``dependencies`` which provides command line utility for printing the result of :ref:`mju_getXMLDependencies`.
MJX
^^^
+1 -1
View File
@@ -3021,6 +3021,7 @@ int mj_saveLastXML(const char* filename, const mjModel* m, char* error, int erro
void mj_freeLastXML(void);
int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int error_sz);
int mj_saveXML(const mjSpec* s, const char* filename, char* error, int error_sz);
void mju_getXMLDependencies(const char* filename, mjStringVec* dependencies);
void mj_step(const mjModel* m, mjData* d);
void mj_step1(const mjModel* m, mjData* d);
void mj_step2(const mjModel* m, mjData* d);
@@ -3182,7 +3183,6 @@ mjtNum mju_rayFlex(const mjModel* m, const mjData* d, int flex_layer, mjtByte fl
const mjtNum* pnt, const mjtNum* vec, int vertid[1]);
mjtNum mju_raySkin(int nface, int nvert, const int* face, const float* vert,
const mjtNum pnt[3], const mjtNum vec[3], int vertid[1]);
void mju_getXMLDependencies(const char* filename, mjStringVec* dependencies);
void mjv_defaultCamera(mjvCamera* cam);
void mjv_defaultFreeCamera(const mjModel* m, mjvCamera* cam);
void mjv_defaultPerturb(mjvPerturb* pert);
+3 -5
View File
@@ -151,6 +151,9 @@ MJAPI int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error,
// Nullable: error
MJAPI int mj_saveXML(const mjSpec* s, const char* filename, char* error, int error_sz);
// Given MJCF filename, fills dependencies with a list of all other asset files it depends on.
// The search is recursive, and the list includes the filename itself.
MJAPI void mju_getXMLDependencies(const char* filename, mjStringVec* dependencies);
//---------------------------------- Main simulation -----------------------------------------------
@@ -644,11 +647,6 @@ MJAPI mjtNum mju_rayFlex(const mjModel* m, const mjData* d, int flex_layer, mjtB
MJAPI mjtNum mju_raySkin(int nface, int nvert, const int* face, const float* vert,
const mjtNum pnt[3], const mjtNum vec[3], int vertid[1]);
//---------------------------------- Dependencies --------------------------------------------------
// Given MJCF filename, fills dependencies with a list of all other files it depends on.
MJAPI void mju_getXMLDependencies(const char* filename, mjStringVec* dependencies);
//---------------------------------- Interaction ---------------------------------------------------
// Set default camera.
+20 -20
View File
@@ -481,6 +481,26 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Save spec to XML file, return 0 on success, -1 otherwise.',
)),
('mju_getXMLDependencies',
FunctionDecl(
name='mju_getXMLDependencies',
return_type=ValueType(name='void'),
parameters=(
FunctionParameterDecl(
name='filename',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
FunctionParameterDecl(
name='dependencies',
type=PointerType(
inner_type=ValueType(name='mjStringVec'),
),
),
),
doc='Given MJCF filename, fills dependencies with a list of all other asset files it depends on. The search is recursive, and the list includes the filename itself.', # pylint: disable=line-too-long
)),
('mj_step',
FunctionDecl(
name='mj_step',
@@ -3925,26 +3945,6 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Intersect ray with skin, return nearest distance or -1 if no intersection, and also output nearest vertex id.', # pylint: disable=line-too-long
)),
('mju_getXMLDependencies',
FunctionDecl(
name='mju_getXMLDependencies',
return_type=ValueType(name='void'),
parameters=(
FunctionParameterDecl(
name='filename',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
FunctionParameterDecl(
name='dependencies',
type=PointerType(
inner_type=ValueType(name='mjStringVec'),
),
),
),
doc='Given MJCF filename, fills dependencies with a list of all other files it depends on.', # pylint: disable=line-too-long
)),
('mjv_defaultCamera',
FunctionDecl(
name='mjv_defaultCamera',
+10
View File
@@ -76,12 +76,19 @@ target_compile_options(compile PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
target_link_libraries(compile Threads::Threads)
target_link_options(compile PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
# Build sample binaries
add_executable(dependencies dependencies.cc)
target_compile_options(dependencies PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
target_link_libraries(dependencies Threads::Threads)
target_link_options(dependencies PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
add_executable(testspeed testspeed.cc)
target_compile_options(testspeed PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
target_link_libraries(testspeed Threads::Threads)
target_link_options(testspeed PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
target_link_libraries(compile mujoco::mujoco)
target_link_libraries(dependencies mujoco::mujoco)
target_link_libraries(testspeed mujoco::mujoco)
# Build samples that require GLFW.
@@ -109,6 +116,7 @@ target_link_options(record PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
embed_in_bundle(basic simulate)
embed_in_bundle(compile simulate)
embed_in_bundle(dependencies simulate)
embed_in_bundle(record simulate)
embed_in_bundle(testspeed simulate)
endif()
@@ -127,6 +135,7 @@ if(_INSTALL_SAMPLES)
TARGETS
basic
compile
dependencies
record
testspeed
INSTALL_DIRECTORY
@@ -140,6 +149,7 @@ if(_INSTALL_SAMPLES)
install(
TARGETS basic
compile
dependencies
record
testspeed
EXPORT ${PROJECT_NAME}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2025 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <mujoco/mujoco.h>
// help
static constexpr char helpstring[] =
"\n Usage: list_dependencies infile\n"
" infile must be in MJCF\n"
" Example: list_dependencies model.xml\n";
// main function
int main(int argc, char** argv) {
// print help if arguments are missing
if (argc!=3 && argc!=2) {
std::cout << helpstring << std::endl;
return EXIT_SUCCESS;
}
mjStringVec dependencies;
mju_getXMLDependencies(argv[1], &dependencies);
std::sort(dependencies.begin(), dependencies.end());
std::cout << "Dependencies:" << std::endl;
for (int i = 0; i < dependencies.size(); ++i) {
std::cout << "\t " << dependencies[i] << std::endl;
}
return EXIT_SUCCESS;
}
+3 -3
View File
@@ -6367,6 +6367,9 @@ public static unsafe extern int mj_saveLastXML([MarshalAs(UnmanagedType.LPStr)]s
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mj_freeLastXML();
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mju_getXMLDependencies([MarshalAs(UnmanagedType.LPStr)]string filename, void* dependencies);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mj_step(mjModel_* m, mjData_* d);
@@ -6757,9 +6760,6 @@ public static unsafe extern double mju_rayFlex(mjModel_* m, mjData_* d, int flex
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern double mju_raySkin(int nface, int nvert, int* face, float* vert, double* pnt, double* vec, int* vertid);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mju_getXMLDependencies([MarshalAs(UnmanagedType.LPStr)]string filename, void* dependencies);
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void mjv_defaultCamera(mjvCamera_* cam);