Improve documentation related to mjSpec element deletion.

PiperOrigin-RevId: 775677830
Change-Id: I02e51b57956b0b6a20c654326b54e001b498dd96
This commit is contained in:
Yuval Tassa
2025-06-25 07:22:31 -07:00
committed by Copybara-Service
parent d0faa3624e
commit 18d5d5d03f
7 changed files with 26 additions and 15 deletions
+1 -2
View File
@@ -8,8 +8,7 @@ Upcoming version (not yet released)
.. admonition:: Breaking API changes
:class: attention
- The functions ``mjs_detachBody`` and ``mjs_detachDefault`` have been replaced by :ref:`mjs_delete`. Additionally,
`:ref:mjs_detach` was added in order to remove an element from the spec without deleting it.
- The functions ``mjs_detachBody`` and ``mjs_detachDefault`` have been replaced by :ref:`mjs_delete`.
- The Python functions ``element.delete`` have been replaced by ``spec.delete(element)``.
General
+20 -8
View File
@@ -96,25 +96,37 @@ Elements cannot be created directly; they are returned to the user by the corres
my_geom->type = mjGEOM_BOX; // set geom type
my_geom->size[0] = my_geom->size[1] = my_geom->size[2] = 0.5; // set box size
mjModel* model = mj_compile(spec, NULL); // compile to mjModel
...
mj_deleteModel(model); // free model
mj_deleteSpec(spec); // free spec
The ``NULL`` second argument to :ref:`mjs_addGeom` is the optional default class pointer. When using defaults
procedurally, default classes are passed in explicitly to element constructors. The global defaults of all elements
(used when no default class is passed in) can be inspected in
`user_init.c <https://github.com/google-deepmind/mujoco/blob/main/src/user/user_init.c>`__.
.. _meMemory:
Memory management
^^^^^^^^^^^^^^^^^
As seen in the examples above, model elements are never allocated by the user directly, but rather returned by a
constructor. The library takes ownership of all elements and frees them when the parent :ref:`mjSpec` is deleted using
:ref:`mj_deleteSpec`. The user is only responsible for freeing :ref:`mjSpec` structs.
.. _meAttachment:
Attachment
^^^^^^^^^^
This framework introduces a powerful new feature: attaching and detaching model subtrees. This feature is already used
to power the :ref:`attach<body-attach>` an :ref:`replicate<replicate>` meta-elements in MJCF. Attachment allows the user
to move or copy a subtree from one model into another, while also copying or moving related referenced assets and
referencing elements from outside the kinematic tree (e.g., actuators and sensors). Similarly, detaching a subtree will
remove all associated elements from the model. The default behavior is to move the child into the parent while
attaching, so subsequent changes to the child will also change the parent. Alternatively, the user can choose to make an
entirely new copy during attach using :ref:`mjs_setDeepCopy`. This flag is temporarily set to true while parsing XMLs.
It is possible to :ref:`attach a body to a frame<mjs_attach>`:
This framework introduces a powerful new feature: attaching and deleting model subtrees. This feature is already used to
power the :ref:`attach<body-attach>` an :ref:`replicate<replicate>` meta-elements in MJCF. Attachment allows the user to
move or copy a subtree from one model into another, while also copying or moving related referenced assets and
referencing elements from outside the kinematic tree (e.g., actuators and sensors). Similarly, deleting a subtree will
remove all associated elements from the model. The default behavior ("shallow copy") is to move the child into the
parent while attaching, so subsequent changes to the child will also change the parent. Alternatively, the user can
choose to make an entirely new copy during attach using :ref:`mjs_setDeepCopy`. This flag is temporarily set to true
while parsing XMLs. It is possible to :ref:`attach a body to a frame<mjs_attach>`:
.. code-block:: C
+1 -1
View File
@@ -605,7 +605,7 @@ Element removal
^^^^^^^^^^^^^^^
The method ``delete()`` removes the corresponding element from the spec, e.g. ``spec.delete(spec.geom('my_geom'))`` will
remove the geom named "my_geom" and all of the elements that reference it. For elements that can have children (bodies
and defaults), ``delete`` removes also all of their children. When detaching body subtrees, all elements which reference
and defaults), ``delete`` also removes all of their children. When deleting body subtrees, all elements which reference
elements in the subtree, will also be removed.
Tree traversal
+1 -1
View File
@@ -1438,7 +1438,7 @@ MJAPI mjsLight* mjs_addLight(mjsBody* body, const mjsDefault* def);
// Add frame to body.
MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe);
// Detach but not delete object corresponding to the given element, return 0 on success.
// Remove object corresponding to the given element, return 0 on success.
MJAPI int mjs_delete(mjSpec* spec, mjsElement* element);
+1 -1
View File
@@ -9175,7 +9175,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
),
),
doc='Detach but not delete object corresponding to the given element, return 0 on success.', # pylint: disable=line-too-long
doc='Remove object corresponding to the given element, return 0 on success.', # pylint: disable=line-too-long
)),
('mjs_addActuator',
FunctionDecl(
+1 -1
View File
@@ -340,7 +340,7 @@ int mj_copyBack(mjSpec* s, const mjModel* m) {
// detach body from mjSpec, return 0 on success
// remove body from mjSpec, return 0 on success
int mjs_delete(mjSpec* s, mjsElement* element) {
mjCModel* model = static_cast<mjCModel*>(s->element);
if (!element) {
+1 -1
View File
@@ -103,7 +103,7 @@ MJAPI mjsLight* mjs_addLight(mjsBody* body, const mjsDefault* def);
// Add frame to body.
MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe);
// Detach but not delete object corresponding to the given element, return 0 on success.
// Remove object corresponding to the given element, return 0 on success.
MJAPI int mjs_delete(mjSpec* s, mjsElement* element);