Object: add functionality to access the object as an index for operators

Add:
- ED_object_in_mode_to_index
- ED_object_in_mode_from_index

Useful for operators that act on a non-active object in multi-edit mode,
so the index can be stored for the operators exec function to read back
the value when redoing an action. Needed to resolve T102680.
This commit is contained in:
Campbell Barton 2023-01-20 12:46:06 +11:00
parent 1184501d5c
commit ebb519652c
Notes: blender-bot 2023-02-14 08:10:06 +01:00
Referenced by issue #102680, Pick shortest Path in UV Editor work incorrectly, if edit several objects
2 changed files with 71 additions and 0 deletions

View File

@ -507,6 +507,31 @@ void ED_object_posemode_set_for_weight_paint(struct bContext *C,
struct Object *ob,
bool is_mode_set);
/**
* Return the index of an object in a mode (typically edit/pose mode).
*
* Useful for operators with multi-mode editing to be able to redo an action on an object
* by it's index which (unlike pointers) the operator can store for redo.
*
* The indices aren't intended to be useful from Python scripts,
* although they are not prevented from passing them in, this is mainly to enable redo.
* For scripts it's more convenient to set the object active before operating on it.
*
* \note The active object is always index 0.
*/
int ED_object_in_mode_to_index(const struct Scene *scene,
struct ViewLayer *view_layer,
eObjectMode mode,
const struct Object *ob);
/**
* Access the object from the index returned by #ED_object_in_mode_to_index.
*/
Object *ED_object_in_mode_from_index(const struct Scene *scene,
struct ViewLayer *view_layer,
eObjectMode mode,
int index);
/* object_modifier.c */
enum {

View File

@ -217,6 +217,52 @@ Object **ED_object_array_in_mode_or_selected(bContext *C,
/** \} */
/* -------------------------------------------------------------------- */
/** \name Object Index Lookup/Creation
* \{ */
int ED_object_in_mode_to_index(const Scene *scene,
ViewLayer *view_layer,
const eObjectMode mode,
const Object *ob)
{
BLI_assert(ob != NULL);
/* NOTE: the `v3d` is always NULL because the purpose of this function is to return
* a reusable index, using the `v3d` only increases the chance the index may become invalid. */
int index = -1;
int i = 0;
FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, NULL, -1, mode, base_iter) {
if (base_iter->object == ob) {
index = i;
break;
}
i++;
}
FOREACH_BASE_IN_MODE_END;
return index;
}
Object *ED_object_in_mode_from_index(const Scene *scene,
ViewLayer *view_layer,
const eObjectMode mode,
int index)
{
BLI_assert(index >= 0);
Object *ob = NULL;
int i = 0;
FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, NULL, -1, mode, base_iter) {
if (index == i) {
ob = base_iter->object;
break;
}
i++;
}
FOREACH_BASE_IN_MODE_END;
return ob;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Hide Operator
* \{ */