diff options
author | Bastien Montagne <b.mont29@gmail.com> | 2019-11-25 19:07:34 +0300 |
---|---|---|
committer | Bastien Montagne <b.mont29@gmail.com> | 2019-11-25 19:42:01 +0300 |
commit | 0eda3bae64913fa858a2a9eef80acd15f3ebd85a (patch) | |
tree | feed25ff9817ddb91ef817a2d00f50b01ee3e215 /source | |
parent | e0cada951982093453a91b80342ce20c4f421fc8 (diff) |
Add 'asset uuid' to IDs.
This commit is a subset of the asset-engine branch, only adding the uuid
struct to data-blocks, with a basic minimal RNA/Python API to use it.
it does not contain anything regarding asset engines and asset
management itself.
Besides being a first step towards full integration of asset engine work
into master, it is also the 'minimal requirement' from the studio here
for next Cosmos production pipeline (regarding own in-house management
tools).
Diffstat (limited to 'source')
19 files changed, 666 insertions, 26 deletions
diff --git a/source/blender/blenkernel/BKE_asset_engine.h b/source/blender/blenkernel/BKE_asset_engine.h new file mode 100644 index 00000000000..4404aa773c1 --- /dev/null +++ b/source/blender/blenkernel/BKE_asset_engine.h @@ -0,0 +1,63 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2015 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file BKE_asset_engine.h + * \ingroup bke + */ + +#ifndef __BKE_ASSET_ENGINE_H__ +#define __BKE_ASSET_ENGINE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct AssetUUID; +struct Main; + +#define ASSETUUID_SUB_EQUAL(_uuida, _uuidb, _member) \ + (memcmp((_uuida)->_member, (_uuidb)->_member, sizeof((_uuida)->_member)) == 0) + +#define ASSETUUID_EQUAL(_uuida, _uuidb) \ + (ASSETUUID_SUB_EQUAL(_uuida, _uuidb, uuid_repository) && \ + ASSETUUID_SUB_EQUAL(_uuida, _uuidb, uuid_asset) && \ + ASSETUUID_SUB_EQUAL(_uuida, _uuidb, uuid_variant) && \ + ASSETUUID_SUB_EQUAL(_uuida, _uuidb, uuid_revision) && \ + ASSETUUID_SUB_EQUAL(_uuida, _uuidb, uuid_view)) + +/* Various helpers */ +unsigned int BKE_asset_uuid_hash(const void *key); +bool BKE_asset_uuid_cmp(const void *a, const void *b); +void BKE_asset_uuid_print(const struct AssetUUID *uuid); + +void BKE_asset_main_search(struct Main *bmain, struct AssetUUID *uuid); + +#ifdef __cplusplus +} +#endif + +#endif /* __BKE_ASSET_ENGINE_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 883518b7a9d..498f4757f84 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -75,6 +75,7 @@ set(SRC intern/appdir.c intern/armature.c intern/armature_update.c + intern/asset_engine.c intern/autoexec.c intern/blender.c intern/blender_copybuffer.c @@ -241,6 +242,7 @@ set(SRC BKE_animsys.h BKE_appdir.h BKE_armature.h + BKE_asset_engine.h BKE_autoexec.h BKE_blender.h BKE_blender_copybuffer.h diff --git a/source/blender/blenkernel/intern/asset_engine.c b/source/blender/blenkernel/intern/asset_engine.c new file mode 100644 index 00000000000..4e63d0baa99 --- /dev/null +++ b/source/blender/blenkernel/intern/asset_engine.c @@ -0,0 +1,116 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2015 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/asset_engine.c + * \ingroup bke + */ + +#include <string.h> + +#include "BLI_utildefines.h" +#include "BLI_hash_mm2a.h" +#include "BLI_listbase.h" + +#include "BKE_asset_engine.h" +#include "BKE_main.h" + +#include "IMB_imbuf.h" + +#include "DNA_ID.h" + +#include "MEM_guardedalloc.h" + +#ifdef WITH_PYTHON +# include "BPY_extern.h" +#endif + +/* Various helpers */ +unsigned int BKE_asset_uuid_hash(const void *key) +{ + BLI_HashMurmur2A mm2a; + const AssetUUID *uuid = key; + BLI_hash_mm2a_init(&mm2a, 0); + BLI_hash_mm2a_add(&mm2a, (const uchar *)uuid->uuid_repository, sizeof(uuid->uuid_repository)); + BLI_hash_mm2a_add(&mm2a, (const uchar *)uuid->uuid_asset, sizeof(uuid->uuid_asset)); + BLI_hash_mm2a_add(&mm2a, (const uchar *)uuid->uuid_variant, sizeof(uuid->uuid_variant)); + BLI_hash_mm2a_add(&mm2a, (const uchar *)uuid->uuid_revision, sizeof(uuid->uuid_revision)); + BLI_hash_mm2a_add(&mm2a, (const uchar *)uuid->uuid_view, sizeof(uuid->uuid_view)); + return BLI_hash_mm2a_end(&mm2a); +} + +bool BKE_asset_uuid_cmp(const void *a, const void *b) +{ + const AssetUUID *uuid1 = a; + const AssetUUID *uuid2 = b; + return !ASSETUUID_EQUAL(uuid1, uuid2); /* Expects false when compared equal... */ +} + +void BKE_asset_uuid_print(const AssetUUID *uuid) +{ + /* TODO print nicer (as 128bit hexadecimal...). */ + printf("[%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d]\n", + uuid->uuid_repository[0], + uuid->uuid_repository[1], + uuid->uuid_repository[2], + uuid->uuid_repository[3], + uuid->uuid_asset[0], + uuid->uuid_asset[1], + uuid->uuid_asset[2], + uuid->uuid_asset[3], + uuid->uuid_variant[0], + uuid->uuid_variant[1], + uuid->uuid_variant[2], + uuid->uuid_variant[3], + uuid->uuid_revision[0], + uuid->uuid_revision[1], + uuid->uuid_revision[2], + uuid->uuid_revision[3], + uuid->uuid_view[0], + uuid->uuid_view[1], + uuid->uuid_view[2], + uuid->uuid_view[3]); +} + +/** Search the whole Main for a given asset uuid. + * + * \note if found, ID is put into uuid->id pointer. */ +void BKE_asset_main_search(Main *bmain, AssetUUID *uuid) +{ + uuid->id = NULL; + + ID *id; + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (id->uuid == NULL) { + continue; + } + if (ASSETUUID_EQUAL(id->uuid, uuid)) { + uuid->id = id; + return; + } + } + FOREACH_MAIN_ID_END; +} diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index e312522b508..8feeb18adc7 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1785,6 +1785,7 @@ void id_clear_lib_data_ex(Main *bmain, ID *id, const bool id_in_mainlist) id_fake_user_clear(id); id->lib = NULL; + MEM_SAFE_FREE(id->uuid); id->tag &= ~(LIB_TAG_INDIRECT | LIB_TAG_EXTERN); id->flag &= ~LIB_INDIRECT_WEAK_LINK; if (id_in_mainlist) { diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index e1b3212a92c..9f0a1c6079b 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -764,6 +764,10 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user) BKE_override_library_free(&id->override_library, do_id_user); } + if (id->uuid) { + MEM_freeN(id->uuid); + } + /* XXX TODO remove animdata handling from each type's freeing func, * and do it here, like for copy! */ } diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index adf3bf00d48..d1c6189ab9c 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -28,6 +28,7 @@ extern "C" { #endif +struct AssetUUID; struct BHead; struct BlendThumbnail; struct FileData; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9c220e59017..1c86af638da 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -102,10 +102,13 @@ #include "BLI_mempool.h" #include "BLI_ghash.h" +#include "RNA_types.h" + #include "BLT_translation.h" #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_asset_engine.h" #include "BKE_brush.h" #include "BKE_collection.h" #include "BKE_colortools.h" @@ -2678,6 +2681,12 @@ static void direct_link_id(FileData *fd, ID *id) if (drawdata) { BLI_listbase_clear((ListBase *)drawdata); } + + if (id->uuid) { + id->uuid = newdataadr(fd, id->uuid); + id->uuid->ibuff = NULL; /* Just in case... */ + id->uuid->width = id->uuid->height = 0; + } } /** \} */ @@ -9303,6 +9312,19 @@ static BHead *read_libblock(FileData *fd, } } + if (id->uuid) { + /* read all data into fd->datamap */ + bhead = read_data_into_oldnewmap(fd, bhead, __func__); + + id->uuid = newdataadr(fd, id->uuid); + id->uuid->ibuff = NULL; /* Just in case... */ + id->uuid->width = id->uuid->height = 0; + + oldnewmap_free_unused(fd->datamap); + oldnewmap_clear(fd->datamap); + return bhead; + } + return blo_bhead_next(fd, bhead); } @@ -11867,6 +11889,11 @@ static void read_library_linked_ids(FileData *basefd, * (known case: some directly linked shapekey from a missing lib...). */ /* BLI_assert(*realid != NULL); */ + if (*realid && id->uuid) { + /* we can give ownership of that pointer to new ID. */ + (*realid)->uuid = id->uuid; + } + /* Now that we have a real ID, replace all pointers to placeholders in * fd->libmap with pointers to the real data-blocks. We do this for all * libraries since multiple might be referencing this ID. */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b3a16b1fb4d..077515c8b05 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -709,6 +709,9 @@ static void write_iddata(void *wd, const ID *id) if (id->properties && !ELEM(GS(id->name), ID_WM)) { IDP_WriteProperty(id->properties, wd); } + if (id->uuid) { + writestruct(wd, DATA, AssetUUID, 1, id->uuid); + } if (id->override_library) { writestruct(wd, DATA, IDOverrideLibrary, 1, id->override_library); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 11f18357f7b..740807690de 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -3111,6 +3111,27 @@ static void outliner_draw_tree_element(bContext *C, ICON_LIBRARY_DATA_DIRECT, alpha_fac); } + if (tselem->id->uuid) { + offsx += UI_UNIT_X; + UI_icon_draw_alpha((float)startx + offsx - 0.5f * ufac, + (float)*starty + 1.5f * ufac, + ICON_SOLO_ON, + alpha_fac); + if (tselem->id->uuid->tag & UUID_TAG_ENGINE_MISSING) { + UI_icon_draw_alpha( + (float)startx + offsx, (float)*starty + 2 * ufac, ICON_GHOST_ENABLED, alpha_fac); + } + else if (tselem->id->uuid->tag & UUID_TAG_ASSET_MISSING) { + /* Nothing special (underlying icon is already 'broken' one)... */ + } + else if (tselem->id->uuid->tag & UUID_TAG_ASSET_RELOAD) { + UI_icon_draw_alpha( + (float)startx + offsx, (float)*starty + 2 * ufac, ICON_FILE_REFRESH, alpha_fac); + } + else { + /* Nothing special (underlying icon is already 'OK' one)... */ + } + } offsx += UI_UNIT_X + 4 * ufac; } else if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_OVERRIDE_LIBRARY(tselem->id)) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 476010a693d..13545e01771 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -696,7 +696,8 @@ static void id_local_cb(bContext *C, if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) { Main *bmain = CTX_data_main(C); /* if the ID type has no special local function, - * just clear the lib */ + * just clear the lib. */ + /* XXX This is very, very, **very** suspicious - should not be handled that way at all!!! */ if (id_make_local(bmain, tselem->id, false, false) == false) { id_clear_lib_data(bmain, tselem->id); } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index fce68b11fe4..43760df9517 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -232,6 +232,58 @@ enum eOverrideLibrary_Flag { OVERRIDE_LIBRARY_AUTO = 1 << 0, /* Allow automatic generation of overriding rules. */ }; +/** + * About Unique identifier. + * + * Stored in a CustomProps once imported. + * Each engine is free to use it as it likes - it will be the only thing passed to it by blender to + * identify repository/asset/variant/version/view. + * Assumed to be 128bits (16 bytes) each, handled as four integers due to lack of real + * bytes proptype in RNA :|. + */ +#define ASSET_UUID_LENGTH 16 + +/* Used to communicate with asset engines outside of 'import' context. */ +typedef struct AssetUUID { + int uuid_repository[4]; + int uuid_asset[4]; + int uuid_variant[4]; + int uuid_revision[4]; + int uuid_view[4]; + short flag; /* Saved. */ + short tag; /* Runtime. */ + + /* Preview. */ + short width; + short height; + char *ibuff; /* RGBA 8bits. */ + + /* Used for load_post... */ + struct ID *id; +} AssetUUID; + +/** + * uuid->flag (persitent, saved in .blend files). + */ +enum { + UUID_FLAG_LAST_REVISION = 1 << 0, /* This asset should always use latest available revision. */ +}; + +/** + * uuid->tag (runtime only). + */ +enum { + UUID_TAG_ENGINE_MISSING = + 1 << 0, /* The asset engine used for this asset is not known by Blender. */ + UUID_TAG_ASSET_MISSING = + 1 << 1, /* The asset engine was found but does not know about this asset (anymore). */ + + UUID_TAG_ASSET_RELOAD = + 1 << 8, /* Set by the asset engine to indicates that that asset has to be reloaded. */ + UUID_TAG_ASSET_NOPREVIEW = + 1 << 9, /* Set by the asset engine to indicates that that asset has no preview. */ +}; + /* watch it: Sequence has identical beginning. */ /** * ID is the first thing included in all serializable types. It @@ -267,6 +319,9 @@ typedef struct ID { /** Reference linked ID which this one overrides. */ IDOverrideLibrary *override_library; + AssetUUID *uuid; + void *pad_v; + /** * Only set for data-blocks which are coming from copy-on-write, points to * the original version of it. @@ -513,6 +568,8 @@ enum { /* RESET_NEVER Datablock is from a library, * and is only used (linked) indirectly through other libraries. */ LIB_TAG_INDIRECT = 1 << 1, + /* RESET_NEVER Datablock is (or is used by) an asset. */ + LIB_TAG_ASSET = 1 << 19, /* RESET_AFTER_USE Flag used internally in readfile.c, * to mark IDs needing to be expanded (only done once). */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 9e8bda2d12f..081be17d392 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -873,27 +873,6 @@ typedef enum eDirEntry_SelectFlag { FILE_SEL_EDITING = (1 << 4), } eDirEntry_SelectFlag; -/* ***** Related to file browser, but never saved in DNA, only here to help with RNA. ***** */ - -/** - * About Unique identifier. - * - * Stored in a CustomProps once imported. - * Each engine is free to use it as it likes - it will be the only thing passed to it by blender to - * identify asset/variant/version (concatenating the three into a single 48 bytes one). - * Assumed to be 128bits, handled as four integers due to lack of real bytes proptype in RNA :|. - */ -#define ASSET_UUID_LENGTH 16 - -/* Used to communicate with asset engines outside of 'import' context. */ -# -# -typedef struct AssetUUID { - int uuid_asset[4]; - int uuid_variant[4]; - int uuid_revision[4]; -} AssetUUID; - # # typedef struct AssetUUIDList { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5bf6fb40c6a..2eb523daa4c 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -70,6 +70,7 @@ extern StructRNA RNA_ArmatureModifier; extern StructRNA RNA_ArmatureSensor; extern StructRNA RNA_ArrayGpencilModifier; extern StructRNA RNA_ArrayModifier; +extern StructRNA RNA_AssetUUID; extern StructRNA RNA_BackgroundImage; extern StructRNA RNA_BevelModifier; extern StructRNA RNA_BezierSplinePoint; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index f3ade54d5ec..f489c75b691 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -30,6 +30,7 @@ set(DEFSRC rna_animation.c rna_animviz.c rna_armature.c + rna_asset.c rna_boid.c rna_brush.c rna_cachefile.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 009a723551e..b78345d3c9e 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -4219,6 +4219,7 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_animation.c", "rna_animation_api.c", RNA_def_animation}, {"rna_animviz.c", NULL, RNA_def_animviz}, {"rna_armature.c", "rna_armature_api.c", RNA_def_armature}, + {"rna_asset.c", NULL, RNA_def_asset}, {"rna_boid.c", NULL, RNA_def_boid}, {"rna_brush.c", NULL, RNA_def_brush}, {"rna_cachefile.c", NULL, RNA_def_cachefile}, diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 49fdf9c67d5..047d869ec13 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -85,8 +85,10 @@ const EnumPropertyItem rna_enum_id_type_items[] = { # include "DNA_anim_types.h" +# include "BLI_hash_mm2a.h" # include "BLI_listbase.h" # include "BLI_math_base.h" +# include "PIL_time.h" # include "BKE_font.h" # include "BKE_idprop.h" @@ -607,6 +609,24 @@ static void rna_ID_animation_data_free(ID *id, Main *bmain) DEG_relations_tag_update(bmain); } +static void rna_ID_asset_uuid_free(ID *id) +{ + MEM_SAFE_FREE(id->uuid); + id->tag &= ~LIB_TAG_ASSET; +} + +static void rna_ID_asset_uuid_create(ID *id) +{ + rna_ID_asset_uuid_free(id); + id->uuid = MEM_callocN(sizeof(*id->uuid), __func__); + /* Add some dummy init for the asset part of the uuid. */ + for (int i = 0; i < 4; i++) { + id->uuid->uuid_asset[i] = (int)BLI_hash_mm2( + id->name + i, sizeof(id->name) - i, (uint)PIL_check_seconds_timer_i()); + } + id->tag |= LIB_TAG_ASSET; +} + # ifdef WITH_PYTHON void **rna_ID_instance(PointerRNA *ptr) { @@ -1504,6 +1524,15 @@ static void rna_def_ID(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, "rna_IDPreview_get", NULL, NULL, NULL); + prop = RNA_def_pointer( + srna, + "asset_uuid", + "AssetUUID", + "Asset UUID", + "Unique identifier of the asset represented by that ID (NULL if not an asset)"); + RNA_def_property_pointer_sdna(prop, NULL, "uuid"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + /* functions */ func = RNA_def_function(srna, "evaluated_get", "rna_ID_evaluated_get"); RNA_def_function_ui_description( @@ -1597,6 +1626,12 @@ static void rna_def_ID(BlenderRNA *brna) "e.g. when calling :class:`bpy.types.Scene.update`"); RNA_def_enum_flag(func, "refresh", update_flag_items, 0, "", "Type of updates to perform"); + func = RNA_def_function(srna, "asset_uuid_create", "rna_ID_asset_uuid_create"); + RNA_def_function_ui_description(func, "Create asset uuid data to this ID"); + + func = RNA_def_function(srna, "asset_uuid_clear", "rna_ID_asset_uuid_free"); + RNA_def_function_ui_description(func, "Clear asset uuid from this ID"); + # ifdef WITH_PYTHON RNA_def_struct_register_funcs(srna, NULL, NULL, "rna_ID_instance"); # endif diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c new file mode 100644 index 00000000000..c445820198d --- /dev/null +++ b/source/blender/makesrna/intern/rna_asset.c @@ -0,0 +1,214 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Foundation (2015) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_asset.c + * \ingroup RNA + */ + +#include "BLI_utildefines.h" + +#include "DNA_ID.h" + +#include "RNA_define.h" + +#include "rna_internal.h" + +#include "BKE_asset_engine.h" + +#ifdef RNA_RUNTIME + +# include "MEM_guardedalloc.h" + +# include "RNA_access.h" + +/* AssetUUID */ + +static void rna_AssetUUID_preview_size_get(PointerRNA *ptr, int *values) +{ + AssetUUID *uuid = ptr->data; + + values[0] = uuid->width; + values[1] = uuid->height; +} + +static void rna_AssetUUID_preview_size_set(PointerRNA *ptr, const int *values) +{ + AssetUUID *uuid = ptr->data; + + uuid->width = values[0]; + uuid->height = values[1]; + + MEM_SAFE_FREE(uuid->ibuff); +} + +static int rna_AssetUUID_preview_pixels_get_length(PointerRNA *ptr, + int length[RNA_MAX_ARRAY_DIMENSION]) +{ + AssetUUID *uuid = ptr->data; + + length[0] = (uuid->ibuff == NULL) ? 0 : uuid->width * uuid->height; + + return length[0]; +} + +static void rna_AssetUUID_preview_pixels_get(PointerRNA *ptr, int *values) +{ + AssetUUID *uuid = ptr->data; + + memcpy(values, uuid->ibuff, uuid->width * uuid->height * sizeof(unsigned int)); +} + +static void rna_AssetUUID_preview_pixels_set(PointerRNA *ptr, const int *values) +{ + AssetUUID *uuid = ptr->data; + + if (!uuid->ibuff) { + uuid->ibuff = MEM_mallocN(sizeof(*uuid->ibuff) * 4 * uuid->width * uuid->height, __func__); + } + + memcpy(uuid->ibuff, values, uuid->width * uuid->height * sizeof(unsigned int)); +} + +#else /* RNA_RUNTIME */ + +/* Much lighter version of asset/variant/revision identifier. */ +static void rna_def_asset_uuid(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + int null_uuid[4] = {0}; + + srna = RNA_def_struct(brna, "AssetUUID", NULL); + RNA_def_struct_sdna(srna, "AssetUUID"); + RNA_def_struct_ui_text( + srna, "Asset UUID", "A unique identifier of an asset (asset engine dependent!)"); + + RNA_def_int_vector(srna, + "uuid_repository", + 4, + null_uuid, + INT_MIN, + INT_MAX, + "Repository UUID", + "Unique identifier of the repository of this asset", + INT_MIN, + INT_MAX); + + RNA_def_int_vector(srna, + "uuid_asset", + 4, + null_uuid, + INT_MIN, + INT_MAX, + "Asset UUID", + "Unique identifier of this asset", + INT_MIN, + INT_MAX); + + RNA_def_int_vector(srna, + "uuid_variant", + 4, + null_uuid, + INT_MIN, + INT_MAX, + "Variant UUID", + "Unique identifier of this asset's variant", + INT_MIN, + INT_MAX); + + RNA_def_int_vector(srna, + "uuid_revision", + 4, + null_uuid, + INT_MIN, + INT_MAX, + "Revision UUID", + "Unique identifier of this asset's revision", + INT_MIN, + INT_MAX); + + RNA_def_int_vector(srna, + "uuid_view", + 4, + null_uuid, + INT_MIN, + INT_MAX, + "View UUID", + "Unique identifier of this asset's view", + INT_MIN, + INT_MAX); + + prop = RNA_def_boolean(srna, + "is_unknown_engine", + false, + "Unknown Asset Engine", + "This AssetUUID is referencing an unknown asset engine"); + RNA_def_property_boolean_sdna(prop, NULL, "tag", UUID_TAG_ENGINE_MISSING); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_boolean(srna, + "is_asset_missing", + false, + "Missing Asset", + "This AssetUUID is no more known by its asset engine"); + RNA_def_property_boolean_sdna(prop, NULL, "tag", UUID_TAG_ASSET_MISSING); + + prop = RNA_def_boolean(srna, + "use_asset_reload", + false, + "Reload Asset", + "The data matching this AssetUUID should be reloaded"); + RNA_def_property_boolean_sdna(prop, NULL, "tag", UUID_TAG_ASSET_RELOAD); + + prop = RNA_def_boolean( + srna, "has_asset_preview", false, "Valid Preview", "This asset has a valid preview"); + RNA_def_property_boolean_negative_sdna(prop, NULL, "tag", UUID_TAG_ASSET_NOPREVIEW); + + prop = RNA_def_int_vector( + srna, "preview_size", 2, NULL, 0, 0, "Preview Size", "Width and height in pixels", 0, 0); + RNA_def_property_subtype(prop, PROP_PIXEL); + RNA_def_property_int_funcs( + prop, "rna_AssetUUID_preview_size_get", "rna_AssetUUID_preview_size_set", NULL); + + prop = RNA_def_property(srna, "preview_pixels", PROP_INT, PROP_NONE); + RNA_def_property_flag(prop, PROP_DYNAMIC); + RNA_def_property_multi_array(prop, 1, NULL); + RNA_def_property_ui_text( + prop, "Preview Pixels", "Preview pixels, as bytes (always RGBA 32bits)"); + RNA_def_property_dynamic_array_funcs(prop, "rna_AssetUUID_preview_pixels_get_length"); + RNA_def_property_int_funcs( + prop, "rna_AssetUUID_preview_pixels_get", "rna_AssetUUID_preview_pixels_set", NULL); + + prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "ID"); + RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP); + RNA_def_property_ui_text( + prop, "Loaded ID", "Pointer to linked/appended data-block, for load_post callback only"); +} + +void RNA_def_asset(BlenderRNA *brna) +{ + rna_def_asset_uuid(brna); +} + +#endif /* RNA_RUNTIME */ diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 94394a4826b..c195ecfd464 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -142,6 +142,7 @@ void RNA_def_action(struct BlenderRNA *brna); void RNA_def_animation(struct BlenderRNA *brna); void RNA_def_animviz(struct BlenderRNA *brna); void RNA_def_armature(struct BlenderRNA *brna); +void RNA_def_asset(struct BlenderRNA *brna); void RNA_def_boid(struct BlenderRNA *brna); void RNA_def_brush(struct BlenderRNA *brna); void RNA_def_cachefile(struct BlenderRNA *brna); diff --git a/source/blender/python/intern/bpy_rna_id_collection.c b/source/blender/python/intern/bpy_rna_id_collection.c index 6ff1849f646..a30fa30cc49 100644 --- a/source/blender/python/intern/bpy_rna_id_collection.c +++ b/source/blender/python/intern/bpy_rna_id_collection.c @@ -28,6 +28,11 @@ #include "BLI_utildefines.h" #include "BLI_bitmap.h" +#include "RNA_access.h" +#include "RNA_types.h" +#include "RNA_enum_types.h" + +#include "BKE_asset_engine.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_library_query.h" @@ -48,10 +53,6 @@ #include "../generic/py_capi_utils.h" #include "../generic/python_utildefines.h" -#include "RNA_access.h" -#include "RNA_types.h" -#include "RNA_enum_types.h" - #include "bpy_rna.h" typedef struct IDUserMapData { @@ -375,6 +376,107 @@ error: return ret; } +PyDoc_STRVAR( + bpy_asset_uuid_search_doc, + ".. method:: asset_uuid_search([uuid_repository=(0,0,0,0)], [uuid_asset=(0,0,0,0)], " + "[uuid_variant=(0,0,0,0)], [uuid_revision=(0,0,0,0)], [uuid_view=(0,0,0,0)])\n" + "\n" + " Search for a given set of uuid elements (defining a single asset) in current list of " + "IDs.\n" + "\n" + " :arg uuid_repository: The uuid of the repository, as an iterable of four integers.\n" + " :type uuid_repository: sequence\n" + " :arg uuid_asset: The uuid of the asset, as an iterable of four integers.\n" + " :type uuid_asset: sequence\n" + " :arg uuid_variant: The uuid of the variant, as an iterable of four integers.\n" + " :type uuid_variant: sequence\n" + " :arg uuid_revision: The uuid of the revision, as an iterable of four integers.\n" + " :type uuid_revision: sequence\n" + " :arg uuid_view: The uuid of the view, as an iterable of four integers.\n" + " :type uuid_view: sequence\n" + " :return: Found ID or None.\n" + " :rtype: ID\n"); +static PyObject *bpy_asset_uuid_search(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) +{ +#if 0 /* If someone knows how to get a proper 'self' in that case... */ + BPy_StructRNA *pyrna = (BPy_StructRNA *)self; + Main *bmain = pyrna->ptr.data; +#else + Main *bmain = G_MAIN; /* XXX Ugly, but should work! */ +#endif + + PyObject *uuid_tupples[5] = {NULL, NULL, NULL, NULL, NULL}; + + PyObject *ret = NULL; + + static const char *_keywords[] = { + "uuid_repository", "uuid_asset", "uuid_variant", "uuid_revision", "uuid_view", NULL}; + static _PyArg_Parser _parser = {"|OOOOO:asset_uuid_search", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast(args, + kwds, + &_parser, + &uuid_tupples[0], + &uuid_tupples[1], + &uuid_tupples[2], + &uuid_tupples[3], + &uuid_tupples[4])) { + return ret; + } + + int uuid_int_array[5][4] = {0}; + + for (int i = 0; i < 5; i++) { + if (uuid_tupples[i] == NULL) { + continue; + } + + PyObject *uuid_items_fast = PySequence_Fast(uuid_tupples[i], __func__); + if (uuid_items_fast == NULL) { + goto error; + } + + PyObject **uuid_items = PySequence_Fast_ITEMS(uuid_items_fast); + Py_ssize_t uuid_items_len = PySequence_Fast_GET_SIZE(uuid_items_fast); + + if (uuid_items_len != 4) { + PyErr_Format(PyExc_TypeError, + "Expected an uuid item to be an iterable of four integers, not %d %.200s", + uuid_items_len, + Py_TYPE(*uuid_items)->tp_name); + Py_DECREF(uuid_items_fast); + goto error; + } + + int *it = uuid_int_array[i]; + for (; uuid_items_len; uuid_items++, it++, uuid_items_len--) { + *it = PyLong_AsLong(*uuid_items); + } + Py_DECREF(uuid_items_fast); + } + + AssetUUID asset_uuid = { + .uuid_repository = {UNPACK4(uuid_int_array[0])}, + .uuid_asset = {UNPACK4(uuid_int_array[1])}, + .uuid_variant = {UNPACK4(uuid_int_array[2])}, + .uuid_revision = {UNPACK4(uuid_int_array[3])}, + .uuid_view = {UNPACK4(uuid_int_array[4])}, + }; + + BKE_asset_main_search(bmain, &asset_uuid); + + if (asset_uuid.id != NULL) { + ret = pyrna_id_CreatePyObject(asset_uuid.id); + } + + else { + Py_INCREF(Py_None); + ret = Py_None; + } + +error: + return ret; +} + int BPY_rna_id_collection_module(PyObject *mod_par) { static PyMethodDef user_map = { @@ -392,5 +494,15 @@ int BPY_rna_id_collection_module(PyObject *mod_par) PyModule_AddObject( mod_par, "_rna_id_collection_batch_remove", PyCFunction_New(&batch_remove, NULL)); + static PyMethodDef asset_uuid_search = { + "asset_uuid_search", + (PyCFunction)bpy_asset_uuid_search, + METH_VARARGS | METH_KEYWORDS, + bpy_asset_uuid_search_doc, + }; + + PyModule_AddObject( + mod_par, "_rna_id_collection_asset_uuid_search", PyCFunction_New(&asset_uuid_search, NULL)); + return 0; } |