PyAPI: add missing options to bpy.data.library.load(..)
Support options which were available from the operator: set_fake, recursive, reuse_local_id & clear_asset_data.
This commit is contained in:
@@ -47,6 +47,28 @@
|
||||
# include "bpy_rna.hh"
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Utilities
|
||||
* \{ */
|
||||
|
||||
struct BoolFlagPair {
|
||||
bool value;
|
||||
uint32_t flag;
|
||||
};
|
||||
static uint32_t bool_flag_pair_as_flag(const BoolFlagPair *bool_flags, int bool_flags_num)
|
||||
{
|
||||
uint32_t flag = 0;
|
||||
for (int i = 0; i < bool_flags_num; i++) {
|
||||
BLI_assert(bool_flags[i].flag);
|
||||
if (bool_flags[i].value) {
|
||||
flag |= bool_flags[i].flag;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
struct BPy_Library {
|
||||
PyObject_HEAD /* Required Python macro. */
|
||||
/* Collection iterator specific parts. */
|
||||
@@ -164,7 +186,11 @@ PyDoc_STRVAR(
|
||||
"filepath, "
|
||||
"link=False, "
|
||||
"relative=False, "
|
||||
"set_fake=False, "
|
||||
"recursive=False, "
|
||||
"reuse_local_id=False, "
|
||||
"assets_only=False, "
|
||||
"clear_asset_data=False, "
|
||||
"create_liboverrides=False, "
|
||||
"reuse_liboverrides=False, "
|
||||
"create_liboverrides_runtime=False)\n"
|
||||
@@ -178,8 +204,18 @@ PyDoc_STRVAR(
|
||||
" :type link: bool\n"
|
||||
" :arg relative: When True the path is stored relative to the open blend file.\n"
|
||||
" :type relative: bool\n"
|
||||
" :arg set_fake: If True, set fake user on appended IDs.\n"
|
||||
" :type set_fake: bool\n"
|
||||
" :arg recursive: If True, also make indirect dependencies of appended libraries local.\n"
|
||||
" :type recursive: bool\n"
|
||||
" :arg reuse_local_id: If True,"
|
||||
"try to re-use previously appended matching ID on new append.\n"
|
||||
" :type reuse_local_id: bool\n"
|
||||
" :arg assets_only: If True, only list data-blocks marked as assets.\n"
|
||||
" :type assets_only: bool\n"
|
||||
" :arg clear_asset_data: If True, "
|
||||
"clear the asset data on append (it is always kept for linked data).\n"
|
||||
" :type clear_asset_data: bool\n"
|
||||
" :arg create_liboverrides: If True and ``link`` is True, liboverrides will\n"
|
||||
" be created for linked data.\n"
|
||||
" :type create_liboverrides: bool\n"
|
||||
@@ -195,15 +231,39 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
|
||||
Main *bmain = static_cast<Main *>(self->ptr->data); /* Typically #G_MAIN */
|
||||
BPy_Library *ret;
|
||||
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
|
||||
bool is_rel = false, is_link = false, use_assets_only = false;
|
||||
bool create_liboverrides = false, reuse_liboverrides = false,
|
||||
create_liboverrides_runtime = false;
|
||||
|
||||
/* #BPy_Library::flag
|
||||
*
|
||||
* - #BLO_LIBLINK_OBDATA_INSTANCE: The caller must manage instancing.
|
||||
* - #BLO_LIBLINK_COLLECTION_INSTANCE: The caller must manage instancing.
|
||||
*/
|
||||
struct {
|
||||
BoolFlagPair is_link = {false, FILE_LINK};
|
||||
BoolFlagPair is_relative = {false, FILE_RELPATH};
|
||||
BoolFlagPair set_fake = {false, BLO_LIBLINK_APPEND_SET_FAKEUSER};
|
||||
BoolFlagPair recursive = {false, BLO_LIBLINK_APPEND_RECURSIVE};
|
||||
BoolFlagPair reuse_local_id = {false, BLO_LIBLINK_APPEND_LOCAL_ID_REUSE};
|
||||
BoolFlagPair assets_only = {false, FILE_ASSETS_ONLY};
|
||||
BoolFlagPair clear_asset_data = {false, BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR};
|
||||
} flag_vars;
|
||||
|
||||
bool create_liboverrides = false;
|
||||
|
||||
/* #BPy_Library::liboverride_flags */
|
||||
struct {
|
||||
BoolFlagPair reuse_liboverrides = {false, BKE_LIBLINK_OVERRIDE_USE_EXISTING_LIBOVERRIDES};
|
||||
BoolFlagPair create_liboverrides_runtime = {false, BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME};
|
||||
} liboverride_flag_vars;
|
||||
|
||||
static const char *_keywords[] = {
|
||||
"filepath",
|
||||
"link",
|
||||
"relative",
|
||||
"set_fake",
|
||||
"recursive",
|
||||
"reuse_local_id",
|
||||
"assets_only",
|
||||
"clear_asset_data",
|
||||
"create_liboverrides",
|
||||
"reuse_liboverrides",
|
||||
"create_liboverrides_runtime",
|
||||
@@ -216,7 +276,11 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
|
||||
"|$"
|
||||
"O&" /* `link` */
|
||||
"O&" /* `relative` */
|
||||
"O&" /* `recursive` */
|
||||
"O&" /* `set_fake` */
|
||||
"O&" /* `reuse_local_id` */
|
||||
"O&" /* `assets_only` */
|
||||
"O&" /* `clear_asset_data` */
|
||||
"O&" /* `create_liboverrides` */
|
||||
"O&" /* `reuse_liboverrides` */
|
||||
"O&" /* `create_liboverrides_runtime` */
|
||||
@@ -230,17 +294,25 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
|
||||
PyC_ParseUnicodeAsBytesAndSize,
|
||||
&filepath_data,
|
||||
PyC_ParseBool,
|
||||
&is_link,
|
||||
&flag_vars.is_link,
|
||||
PyC_ParseBool,
|
||||
&is_rel,
|
||||
&flag_vars.is_relative,
|
||||
PyC_ParseBool,
|
||||
&use_assets_only,
|
||||
&flag_vars.recursive,
|
||||
PyC_ParseBool,
|
||||
&flag_vars.set_fake,
|
||||
PyC_ParseBool,
|
||||
&flag_vars.reuse_local_id,
|
||||
PyC_ParseBool,
|
||||
&flag_vars.assets_only,
|
||||
PyC_ParseBool,
|
||||
&flag_vars.clear_asset_data,
|
||||
PyC_ParseBool,
|
||||
&create_liboverrides,
|
||||
PyC_ParseBool,
|
||||
&reuse_liboverrides,
|
||||
&liboverride_flag_vars.reuse_liboverrides,
|
||||
PyC_ParseBool,
|
||||
&create_liboverrides_runtime))
|
||||
&liboverride_flag_vars.create_liboverrides_runtime))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -271,19 +343,48 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_link && create_liboverrides) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` is False but `create_liboverrides` is True");
|
||||
return nullptr;
|
||||
if (flag_vars.is_link.value) {
|
||||
/* Link. */
|
||||
if (flag_vars.set_fake.value) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` must be False if `set_fake` is True");
|
||||
return nullptr;
|
||||
}
|
||||
if (flag_vars.recursive.value) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` must be False if `recursive` is True");
|
||||
return nullptr;
|
||||
}
|
||||
if (flag_vars.reuse_local_id.value) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` must be False if `reuse_local_id` is True");
|
||||
return nullptr;
|
||||
}
|
||||
if (flag_vars.clear_asset_data.value) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` must be False if `clear_asset_data` is True");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (!create_liboverrides && reuse_liboverrides) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"`create_liboverrides` is False but `reuse_liboverrides` is True");
|
||||
return nullptr;
|
||||
else {
|
||||
/* Append. */
|
||||
if (create_liboverrides) {
|
||||
PyErr_SetString(PyExc_ValueError, "`link` is False but `create_liboverrides` is True");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (!create_liboverrides && create_liboverrides_runtime) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"`create_liboverrides` is False but `create_liboverrides_runtime` is True");
|
||||
return nullptr;
|
||||
|
||||
if (create_liboverrides) {
|
||||
/* Library overrides. */
|
||||
}
|
||||
else {
|
||||
/* Library overrides (disabled). */
|
||||
if (liboverride_flag_vars.reuse_liboverrides.value) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"`create_liboverrides` is False but `reuse_liboverrides` is True");
|
||||
return nullptr;
|
||||
}
|
||||
if (liboverride_flag_vars.create_liboverrides_runtime.value) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"`create_liboverrides` is False but `create_liboverrides_runtime` is True");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ret = PyObject_New(BPy_Library, &bpy_lib_Type);
|
||||
@@ -295,14 +396,16 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
|
||||
ret->bmain_is_temp = (bmain != bmain_base);
|
||||
|
||||
ret->blo_handle = nullptr;
|
||||
ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0) |
|
||||
(use_assets_only ? FILE_ASSETS_ONLY : 0));
|
||||
|
||||
ret->flag = bool_flag_pair_as_flag(reinterpret_cast<const BoolFlagPair *>(&flag_vars),
|
||||
sizeof(flag_vars) / sizeof(BoolFlagPair));
|
||||
|
||||
ret->create_liboverrides = create_liboverrides;
|
||||
ret->liboverride_flags = eBKELibLinkOverride(
|
||||
create_liboverrides ?
|
||||
((reuse_liboverrides ? BKE_LIBLINK_OVERRIDE_USE_EXISTING_LIBOVERRIDES : 0) |
|
||||
(create_liboverrides_runtime ? BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME : 0)) :
|
||||
0);
|
||||
ret->liboverride_flags = create_liboverrides ?
|
||||
eBKELibLinkOverride(bool_flag_pair_as_flag(
|
||||
reinterpret_cast<const BoolFlagPair *>(&liboverride_flag_vars),
|
||||
sizeof(liboverride_flag_vars) / sizeof(BoolFlagPair))) :
|
||||
eBKELibLinkOverride(0);
|
||||
|
||||
ret->dict = _PyDict_NewPresized(INDEX_ID_MAX);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user