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
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_asset_engine.h65
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/asset_engine.c127
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c2
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c38
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c28
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c4
-rw-r--r--source/blender/makesdna/DNA_ID.h60
-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.c112
-rw-r--r--source/blender/python/intern/bpy_rna_id_collection.h1
-rw-r--r--source/blender/python/intern/bpy_rna_types_capi.c6
20 files changed, 704 insertions, 24 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..6ad9de6918d
--- /dev/null
+++ b/source/blender/blenkernel/BKE_asset_engine.h
@@ -0,0 +1,65 @@
+/*
+ * ***** 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 */
+void BKE_asset_uuid_runtime_reset(struct AssetUUID *uuid);
+
+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 b9054d29752..92e0904c568 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -76,6 +76,7 @@ set(SRC
intern/armature.c
intern/armature_deform.c
intern/armature_update.c
+ intern/asset_engine.c
intern/autoexec.c
intern/blender.c
intern/blender_copybuffer.c
@@ -266,6 +267,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..b309db81f88
--- /dev/null
+++ b/source/blender/blenkernel/intern/asset_engine.c
@@ -0,0 +1,127 @@
+/*
+ * ***** 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 */
+void BKE_asset_uuid_runtime_reset(AssetUUID *uuid) {
+ uuid->preview_image_buffer = NULL;
+ uuid->preview_width = uuid->preview_height = 0;
+ uuid->tag = 0;
+ uuid->id = NULL;
+}
+
+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("[%.10d,%.10d,%.10d,%.10d]"
+ "[%.10d,%.10d,%.10d,%.10d]"
+ "[%.10d,%.10d,%.10d,%.10d]"
+ "[%.10d,%.10d,%.10d,%.10d]"
+ "[%.10d,%.10d,%.10d,%.10d]\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/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index b4f2caac861..9d7671322ea 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -63,6 +63,8 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
}
BKE_animdata_free(id, do_id_user);
+
+ MEM_SAFE_FREE(id->uuid);
}
void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index d4246056efe..777a4fb9dfa 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -29,6 +29,7 @@
#include "BKE_armature.h"
#include "BKE_collection.h"
#include "BKE_curve.h"
+#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e4822c4cb7f..9a5f6ac6bbc 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -108,11 +108,14 @@
#include "BLI_mempool.h"
#include "BLI_threads.h"
+#include "RNA_types.h"
+
#include "BLT_translation.h"
#include "BKE_action.h"
#include "BKE_anim_data.h"
#include "BKE_armature.h"
+#include "BKE_asset_engine.h"
#include "BKE_brush.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
@@ -2876,6 +2879,12 @@ static void direct_link_id_common(
BLI_listbase_clear((ListBase *)drawdata);
}
+ if (id->uuid) {
+ BLO_read_data_address(reader, &id->uuid);
+ /* Make sure runtime fields are always zeroed out. */
+ BKE_asset_uuid_runtime_reset(id->uuid);
+ }
+
/* Handle 'private IDs'. */
direct_link_id_embedded_id(reader, current_library, id, id_old);
}
@@ -9555,6 +9564,18 @@ static BHead *read_libblock(FileData *fd,
}
}
+ if (id->uuid) {
+ /* Read all data into fd->datamap. */
+ bhead = read_data_into_datamap(fd, bhead, __func__);
+
+ id->uuid = newdataadr(fd, id->uuid);
+ /* Make sure runtime fields are always zeroed out. */
+ BKE_asset_uuid_runtime_reset(id->uuid);
+
+ oldnewmap_clear(fd->datamap);
+ return bhead;
+ }
+
direct_link_id(fd, main, id_tag, id, id_old);
return blo_bhead_next(fd, bhead);
}
@@ -12134,6 +12155,21 @@ 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) {
+ /* it is important to keep the UUID we stored in that .blend file, not the (potentially
+ * different) one we get from the library, updating UUID should be handled by asset
+ * engine later - even though changing UUID is not recommended in any case. */
+ if ((*realid)->uuid != NULL) {
+ MEM_SAFE_FREE((*realid)->uuid);
+ }
+ /* We can give ownership of that pointer to new ID. */
+ (*realid)->uuid = id->uuid;
+ id->uuid = NULL;
+ }
+ else {
+ MEM_SAFE_FREE(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. */
@@ -12148,6 +12184,8 @@ static void read_library_linked_ids(FileData *basefd,
/* Clear GHash and free link placeholder IDs of the current type. */
BLI_ghash_clear(loaded_ids, NULL, NULL);
+ /* Note: this is currently just freeing ID struct itself, assuming there is no remaining
+ * allocated sub-data owned by this ID. */
BLI_freelistN(&pending_free_ids);
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 4e0325e72fa..d8576b4c6de 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -738,6 +738,9 @@ static void write_iddata(BlendWriter *writer, ID *id)
if (id->properties && !ELEM(GS(id->name), ID_WM)) {
IDP_WriteProperty(id->properties, writer);
}
+ if (id->uuid) {
+ BLO_write_struct(writer, AssetUUID, id->uuid);
+ }
if (id->override_library) {
BLO_write_struct(writer, IDOverrideLibrary, id->override_library);
@@ -3926,6 +3929,11 @@ static void write_libraries(WriteData *wd, Main *main)
BLI_assert(0);
}
writestruct(wd, ID_LINK_PLACEHOLDER, ID, 1, id);
+ /* It is mandatory to write id's asset uuid reference for placeholders too, otherwise
+ * the whole asset info would be completely lost when reloading the linked data-block,
+ * especially in case it is not immediately found and needs to go through the whole
+ * 'asset engine update' process after main .blend read process is finished. */
+ write_iddata(&writer, id);
}
}
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 6ea1d74112d..5eee97e3fee 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -3116,6 +3116,34 @@ static void outliner_draw_tree_element(bContext *C,
(float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, lib_icon, alpha_fac);
offsx += UI_UNIT_X + 4 * ufac;
}
+ else {
+ UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
+ (float)*starty + 2 * ufac,
+ 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;
}
GPU_blend(false);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index d04402f989c..51b919cd0dc 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -729,7 +729,9 @@ 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.
+ * Probably best thing to do here is to simply not do anything. */
if (BKE_lib_id_make_local(bmain, tselem->id, false, 0) == false) {
BKE_lib_id_clear_library_data(bmain, tselem->id);
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 60cedfe3c8a..660f0121699 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -233,6 +233,61 @@ typedef struct IDOverrideLibrary {
IDOverrideLibraryRuntime *runtime;
} IDOverrideLibrary;
+/**
+ * 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;
+
+ /* Everything below this comment is runtime data. */
+ short tag;
+
+ /* Preview. */
+ short preview_width;
+ short preview_height;
+ char *preview_image_buffer; /* RGBA 8bits. */
+
+ /* Used for load_post and other temporary storage of the ID itself in its AssetUUID.
+ * Usage and scope are similar to the `ID.newid` pointer. */
+ 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 indicate that this asset has to be reloaded. */
+ UUID_TAG_ASSET_NOPREVIEW =
+ 1 << 9, /* Set by the asset engine to indicate that this asset has no preview. */
+};
+
/* watch it: Sequence has identical beginning. */
/**
* ID is the first thing included in all serializable types. It
@@ -285,6 +340,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.
@@ -547,6 +605,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 1cb42b333c7..83489477a8f 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -874,27 +874,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 53bb8899855..ce53454319a 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -67,6 +67,7 @@ extern StructRNA RNA_ArmatureGpencilModifier;
extern StructRNA RNA_ArmatureModifier;
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 980e3eadd34..eaea895746e 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 59087df16dd..8d61b21759f 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -4258,6 +4258,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 46001f27fef..bb67783622b 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -89,8 +89,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_anim_data.h"
# include "BKE_font.h"
@@ -627,6 +629,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)
{
@@ -1526,6 +1546,15 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
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(
@@ -1619,6 +1648,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..9edb623914b
--- /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->preview_width;
+ values[1] = uuid->preview_height;
+}
+
+static void rna_AssetUUID_preview_size_set(PointerRNA *ptr, const int *values)
+{
+ AssetUUID *uuid = ptr->data;
+
+ uuid->preview_width = values[0];
+ uuid->preview_height = values[1];
+
+ MEM_SAFE_FREE(uuid->preview_image_buffer);
+}
+
+static int rna_AssetUUID_preview_pixels_get_length(PointerRNA *ptr,
+ int length[RNA_MAX_ARRAY_DIMENSION])
+{
+ AssetUUID *uuid = ptr->data;
+
+ length[0] = (uuid->preview_image_buffer == NULL) ? 0 : uuid->preview_width * uuid->preview_height;
+
+ return length[0];
+}
+
+static void rna_AssetUUID_preview_pixels_get(PointerRNA *ptr, int *values)
+{
+ AssetUUID *uuid = ptr->data;
+
+ memcpy(values, uuid->preview_image_buffer, uuid->preview_width * uuid->preview_height * sizeof(unsigned int));
+}
+
+static void rna_AssetUUID_preview_pixels_set(PointerRNA *ptr, const int *values)
+{
+ AssetUUID *uuid = ptr->data;
+
+ if (!uuid->preview_image_buffer) {
+ uuid->preview_image_buffer = MEM_mallocN(sizeof(*uuid->preview_image_buffer) * 4 * uuid->preview_width * uuid->preview_height, __func__);
+ }
+
+ memcpy(uuid->preview_image_buffer, values, uuid->preview_width * uuid->preview_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 0783addd78b..71971cf3cca 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -150,6 +150,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 b607f1635e6..bd194a6293d 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_bitmap.h"
#include "BLI_utildefines.h"
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+#include "RNA_types.h"
+
+#include "BKE_asset_engine.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@@ -348,6 +353,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 /* TODO: Find a proper way of getting bmain from `self ` in this 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;
+}
+
PyDoc_STRVAR(bpy_orphans_purge_doc,
".. method:: orphans_purge()\n"
"\n"
@@ -403,3 +509,9 @@ PyMethodDef BPY_rna_id_collection_orphans_purge_method_def = {
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
bpy_orphans_purge_doc,
};
+PyMethodDef BPY_rna_id_collection_asset_uuid_search_method_def = {
+ "asset_uuid_search",
+ (PyCFunction)bpy_asset_uuid_search,
+ METH_STATIC | METH_VARARGS | METH_KEYWORDS,
+ bpy_asset_uuid_search_doc,
+};
diff --git a/source/blender/python/intern/bpy_rna_id_collection.h b/source/blender/python/intern/bpy_rna_id_collection.h
index ee8f4c666a8..9d8bd67b211 100644
--- a/source/blender/python/intern/bpy_rna_id_collection.h
+++ b/source/blender/python/intern/bpy_rna_id_collection.h
@@ -24,5 +24,6 @@
extern PyMethodDef BPY_rna_id_collection_user_map_method_def;
extern PyMethodDef BPY_rna_id_collection_batch_remove_method_def;
extern PyMethodDef BPY_rna_id_collection_orphans_purge_method_def;
+extern PyMethodDef BPY_rna_id_collection_asset_uuid_search_method_def;
#endif /* __BPY_RNA_ID_COLLECTION_H__ */
diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c
index 5a2ba4a5cdb..477f1e98d7b 100644
--- a/source/blender/python/intern/bpy_rna_types_capi.c
+++ b/source/blender/python/intern/bpy_rna_types_capi.c
@@ -55,6 +55,7 @@ static struct PyMethodDef pyrna_blenddata_methods[] = {
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_user_map_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_batch_remove_method_def */
{NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_orphans_purge_method_def */
+ {NULL, NULL, 0, NULL}, /* #BPY_rna_id_collection_asset_uuid_search_method_def */
{NULL, NULL, 0, NULL},
};
@@ -195,8 +196,9 @@ void BPY_rna_types_extend_capi(void)
ARRAY_SET_ITEMS(pyrna_blenddata_methods,
BPY_rna_id_collection_user_map_method_def,
BPY_rna_id_collection_batch_remove_method_def,
- BPY_rna_id_collection_orphans_purge_method_def);
- BLI_assert(ARRAY_SIZE(pyrna_blenddata_methods) == 4);
+ BPY_rna_id_collection_orphans_purge_method_def,
+ BPY_rna_id_collection_asset_uuid_search_method_def);
+ BLI_assert(ARRAY_SIZE(pyrna_blenddata_methods) == 5);
pyrna_struct_type_extend_capi(&RNA_BlendData, pyrna_blenddata_methods, NULL);
/* BlendDataLibraries */