'users of ID' py API.

This mainly adds bpy.data.user_map() method, which goes over the whole Main database
to build a mapping (dict) {ID: {users_of_that_ID}}.

Very handy to check and debug ID usages, but could also be really valuable for py addons
creating temporary scenes, or some exporters, etc.

Note: current code in master's libquery misses some IDs (and reports some it should not,
like nodetrees), this is fixed in id-remap but still needs serious review before going to master.
This basically means that current bpy.data.user_map() **will not** report a complete and exhaustive
state of dependencies between IDs. Should work OK in most cases though.

Original work/idea comes from id-remap branch, was heavily reworked by @campbellbarton
and myself for master.

Reviewers: campbellbarton, sergey

Differential Revision: https://developer.blender.org/D1678
This commit is contained in:
2016-01-06 19:34:42 +01:00
parent ea7a2766f6
commit 4acf0f05a1
10 changed files with 434 additions and 0 deletions

View File

@@ -37,6 +37,7 @@
#include "RNA_types.h"
#include "BLI_bitmap.h"
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
@@ -1176,6 +1177,69 @@ static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *pr
return 0;
}
/**
* Takes a set of strings and map it to and array of booleans.
*
* Useful when the values aren't flags.
*
* \param type_convert_sign: Maps signed to unsuigned range,
* needed when we want to use the full range of a signed short/char.
*/
BLI_bitmap *pyrna_set_to_enum_bitmap(
EnumPropertyItem *items, PyObject *value,
int type_size, bool type_convert_sign,
int bitmap_size,
const char *error_prefix)
{
/* set looping */
Py_ssize_t pos = 0;
Py_ssize_t hash = 0;
PyObject *key;
BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__);
while (_PySet_NextEntry(value, &pos, &key, &hash)) {
const char *param = _PyUnicode_AsString(key);
if (param == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s expected a string, not %.200s",
error_prefix, Py_TYPE(key)->tp_name);
goto error;
}
int ret;
if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
goto error;
}
int index = ret;
if (type_convert_sign) {
if (type_size == 2) {
union { signed short as_signed; unsigned short as_unsigned; } ret_convert;
ret_convert.as_signed = (signed short)ret;
index = (int)ret_convert.as_unsigned;
}
else if (type_size == 1) {
union { signed char as_signed; unsigned char as_unsigned; } ret_convert;
ret_convert.as_signed = (signed char)ret;
index = (int)ret_convert.as_unsigned;
}
else {
BLI_assert(0);
}
}
BLI_assert(index < bitmap_size);
BLI_BITMAP_ENABLE(bitmap, index);
}
return bitmap;
error:
MEM_freeN(bitmap);
return NULL;
}
/* 'value' _must_ be a set type, error check before calling */
int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
{