1
1

Compare commits

...

13 Commits

Author SHA1 Message Date
0829cebeb0 Merge branch 'master' into asset-uuid--archived 2020-07-01 17:13:57 +02:00
cfde6ebf45 Merge branch 'master' into asset-uuid 2020-06-16 11:31:33 +02:00
5e50380ddc Merge branch 'master' into asset-uuid 2020-06-13 22:54:07 +02:00
15e6f9012c Merge branch 'master' into asset-uuid 2020-06-11 11:55:40 +02:00
0b6def7059 Fixes for changes in master 2020-06-11 11:54:45 +02:00
a8b24ca61b Merge branch 'master' into asset-uuid 2020-06-11 10:13:12 +02:00
15a97791c8 Remove the Amber asset engine code, this has nothing to do in that patch. 2019-11-26 18:15:21 +01:00
f3ae50c765 Rename some variables in AssetUUID struct. 2019-11-26 17:59:51 +01:00
cdacfc2f47 Some more minor fixes/cleanups. 2019-11-26 17:45:55 +01:00
67ee496c1b Updates from code review.
Mostly various cleanups, and a few important fixes too (some potential
memleaks, missing writing of UUID struct for ID placeholders of linked
data-block in writefile.c).
2019-11-26 17:34:11 +01:00
2563953366 Merge branch 'master' into asset-uuid 2019-11-26 15:49:49 +01:00
bc13ceba27 Merge branch 'master' into asset-uuid 2019-11-25 17:54:58 +01:00
0eda3bae64 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).
2019-11-25 17:42:01 +01:00
20 changed files with 704 additions and 24 deletions

View File

@@ -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__ */

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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))

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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). */

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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

View File

@@ -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},

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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,
};

View File

@@ -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__ */

View File

@@ -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 */