Add body.find_all() to Python bindings.
This enables to generate a list of all body children of a given type. Also, add recursive option to mjs_firstChild and mjs_nextChild. Fixes #2112. PiperOrigin-RevId: 681039348 Change-Id: Iebbb26fd5ec314150206edfdddd88633baa0bec6
This commit is contained in:
committed by
Copybara-Service
parent
8a825e6050
commit
89aea5e217
+14
-4
@@ -655,17 +655,27 @@ void mjs_setDefault(mjsElement* element, mjsDefault* defspec) {
|
||||
|
||||
|
||||
// return first child of selected type
|
||||
mjsElement* mjs_firstChild(mjsBody* body, mjtObj type) {
|
||||
mjsElement* mjs_firstChild(mjsBody* body, mjtObj type, int recurse) {
|
||||
mjCBody* bodyC = static_cast<mjCBody*>(body->element);
|
||||
return bodyC->NextChild(NULL, type);
|
||||
try {
|
||||
return bodyC->NextChild(NULL, type, recurse);
|
||||
} catch (mjCError& e) {
|
||||
bodyC->model->SetError(e);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return body's next child; return NULL if child is last
|
||||
mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child) {
|
||||
mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child, int recurse) {
|
||||
mjCBody* bodyC = static_cast<mjCBody*>(body->element);
|
||||
return bodyC->NextChild(child);
|
||||
try {
|
||||
return bodyC->NextChild(child, child->elemtype, recurse);
|
||||
} catch(mjCError& e) {
|
||||
bodyC->model->SetError(e);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -218,11 +218,12 @@ MJAPI int mjs_getId(mjsElement* element);
|
||||
|
||||
//---------------------------------- Tree traversal ------------------------------------------------
|
||||
|
||||
// Return body's first child of given type.
|
||||
MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
||||
// Return body's first child of given type. If recurse is nonzero, also search the body's subtree.
|
||||
MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type, int recurse);
|
||||
|
||||
// Return body's next child of the same type; return NULL if child is last.
|
||||
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
||||
// If recurse is nonzero, also search the body's subtree.
|
||||
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child, int recurse);
|
||||
|
||||
// Return spec's first element of selected type.
|
||||
MJAPI mjsElement* mjs_firstElement(mjSpec* s, mjtObj type);
|
||||
|
||||
@@ -921,6 +921,13 @@ mjsElement* mjCModel::NextObject(mjsElement* object, mjtObj type) {
|
||||
|
||||
switch (type) {
|
||||
case mjOBJ_BODY:
|
||||
if (!object) {
|
||||
return bodies_[0]->spec.element;
|
||||
} else if (object == bodies_[0]->spec.element) {
|
||||
return bodies_[0]->NextChild(NULL, type, /*recursive=*/true);
|
||||
} else {
|
||||
return bodies_[0]->NextChild(object, type, /*recursive=*/true);
|
||||
}
|
||||
case mjOBJ_SITE:
|
||||
case mjOBJ_GEOM:
|
||||
case mjOBJ_JOINT:
|
||||
|
||||
@@ -1338,6 +1338,9 @@ mjsElement* mjCBody::NextChild(mjsElement* child, mjtObj type, bool recursive) {
|
||||
candidate = GetNext(frames, child, recursive);
|
||||
break;
|
||||
default:
|
||||
throw mjCError(this,
|
||||
"Body.NextChild supports the types: body, frame, geom, "
|
||||
"site, light, camera");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user