From 4884153823865bbe4bdd365162c71bb45df4081f Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 28 Jan 2021 18:04:10 +0100 Subject: BPY: allow `bpy.data.libraries.load()` to filter out non-asset data-blocks. Differential Revision: https://developer.blender.org/D10237 --- source/blender/blenloader/BLO_readfile.h | 4 ++- source/blender/blenloader/intern/blend_validate.c | 2 +- source/blender/blenloader/intern/readblenentry.c | 12 +++++++-- source/blender/imbuf/intern/thumbs_blend.c | 2 +- source/blender/python/intern/bpy_library_load.c | 30 ++++++++++++++++------- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 1d7c5d8a1d3..7dbe73cbd6a 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -129,7 +129,9 @@ BlendHandle *BLO_blendhandle_from_memory(const void *mem, int memsize); struct LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, - int *tot_names); + + const bool use_assets_only, + int *r_tot_names); struct LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh, int ofblocktype, int *tot_info_items); diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c index c281e2fa643..ea3ecc21ecf 100644 --- a/source/blender/blenloader/intern/blend_validate.c +++ b/source/blender/blenloader/intern/blend_validate.c @@ -112,7 +112,7 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports) } int totnames = 0; - LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), &totnames); + LinkNode *names = BLO_blendhandle_get_datablock_names(bh, GS(id->name), false, &totnames); for (; id != NULL; id = id->next) { if (id->lib == NULL) { is_valid = false; diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 296480fc2e4..f1b15b61d06 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -135,9 +135,14 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp) * \param bh: The blendhandle to access. * \param ofblocktype: The type of names to get. * \param tot_names: The length of the returned list. + * \param use_assets_only: Only list IDs marked as assets. * \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN(). */ -LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, int *tot_names) +LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, + int ofblocktype, + + const bool use_assets_only, + int *r_tot_names) { FileData *fd = (FileData *)bh; LinkNode *names = NULL; @@ -147,6 +152,9 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { if (bhead->code == ofblocktype) { const char *idname = blo_bhead_id_name(fd, bhead); + if (use_assets_only && blo_bhead_id_asset_data_address(fd, bhead) == NULL) { + continue; + } BLI_linklist_prepend(&names, BLI_strdup(idname + 2)); tot++; @@ -156,7 +164,7 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, } } - *tot_names = tot; + *r_tot_names = tot; return names; } diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 486db07597f..0d1fa354b3e 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -57,7 +57,7 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const /* Note: we should handle all previews for a same group at once, would avoid reopening * `.blend` file for each and every ID. However, this adds some complexity, * so keep it for later. */ - names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames); + names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, false, &nnames); previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs); BLO_blendhandle_close(libfiledata); diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index c6f0fbd3a2b..69a6bd1ebbf 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -173,7 +173,7 @@ static PyTypeObject bpy_lib_Type = { PyDoc_STRVAR( bpy_lib_load_doc, - ".. method:: load(filepath, link=False, relative=False)\n" + ".. method:: load(filepath, link=False, assets_only=False, relative=False)\n" "\n" " Returns a context manager which exposes 2 library objects on entering.\n" " Each object has attributes matching bpy.data which are lists of strings to be linked.\n" @@ -182,6 +182,8 @@ PyDoc_STRVAR( " :type filepath: string\n" " :arg link: When False reference to the original file is lost.\n" " :type link: bool\n" + " :arg assets_only: If True, only list data-blocks marked as assets.\n" + " :type assets_only: bool\n" " :arg relative: When True the path is stored relative to the open blend file.\n" " :type relative: bool\n"); static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kw) @@ -189,12 +191,20 @@ static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject * Main *bmain = CTX_data_main(BPY_context_get()); BPy_Library *ret; const char *filename = NULL; - bool is_rel = false, is_link = false; - - static const char *_keywords[] = {"filepath", "link", "relative", NULL}; - static _PyArg_Parser _parser = {"s|O&O&:load", _keywords, 0}; - if (!_PyArg_ParseTupleAndKeywordsFast( - args, kw, &_parser, &filename, PyC_ParseBool, &is_link, PyC_ParseBool, &is_rel)) { + bool is_rel = false, is_link = false, use_assets_only = false; + + static const char *_keywords[] = {"filepath", "link", "relative", "assets_only", NULL}; + static _PyArg_Parser _parser = {"s|O&O&O&:load", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast(args, + kw, + &_parser, + &filename, + PyC_ParseBool, + &is_link, + PyC_ParseBool, + &is_rel, + PyC_ParseBool, + &use_assets_only)) { return NULL; } @@ -205,7 +215,8 @@ static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject * BLI_path_abs(ret->abspath, BKE_main_blendfile_path(bmain)); ret->blo_handle = NULL; - ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0)); + ret->flag = ((is_link ? FILE_LINK : 0) | (is_rel ? FILE_RELPATH : 0) | + (use_assets_only ? FILE_ASSETS_ONLY : 0)); ret->dict = _PyDict_NewPresized(MAX_LIBARRAY); @@ -218,7 +229,8 @@ static PyObject *_bpy_names(BPy_Library *self, int blocktype) LinkNode *l, *names; int totnames; - names = BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames); + names = BLO_blendhandle_get_datablock_names( + self->blo_handle, blocktype, (self->flag & FILE_ASSETS_ONLY) != 0, &totnames); list = PyList_New(totnames); if (names) { -- cgit v1.2.3