Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <b.mont29@gmail.com>2019-11-25 19:07:34 +0300
committerBastien Montagne <b.mont29@gmail.com>2019-11-25 19:42:01 +0300
commit0eda3bae64913fa858a2a9eef80acd15f3ebd85a (patch)
treefeed25ff9817ddb91ef817a2d00f50b01ee3e215 /source
parente0cada951982093453a91b80342ce20c4f421fc8 (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')
-rw-r--r--source/blender/blenkernel/BKE_asset_engine.h63
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/asset_engine.c116
-rw-r--r--source/blender/blenkernel/intern/library.c1
-rw-r--r--source/blender/blenkernel/intern/library_remap.c4
-rw-r--r--source/blender/blenloader/BLO_readfile.h1
-rw-r--r--source/blender/blenloader/intern/readfile.c27
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c21
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c3
-rw-r--r--source/blender/makesdna/DNA_ID.h57
-rw-r--r--source/blender/makesdna/DNA_space_types.h21
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt1
-rw-r--r--source/blender/makesrna/intern/makesrna.c1
-rw-r--r--source/blender/makesrna/intern/rna_ID.c35
-rw-r--r--source/blender/makesrna/intern/rna_asset.c214
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/python/intern/bpy_rna_id_collection.c120
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;
}