1
1

Compare commits

...

43 Commits

Author SHA1 Message Date
31acdbed95 Add custom property support for assets
I didn't do this earlier because I was afraid it would make reading of asset
data (and asset data only!) difficult. Mainly because custom properties could
store pointers to other data, that would have to be read too then (e.g. an
object). But turns out, we can easily disable custom pointers to other
data-blocks, so reading stays simple :).
2020-11-23 14:14:55 +01:00
3f33bf6195 Merge branch 'master' into asset-metadata 2020-11-23 13:31:24 +01:00
d7c757bedd Fix crash loading some files after recent merge
Caused by badly resolved merge conflicts.
2020-11-13 00:13:17 +01:00
87507df705 Merge branch 'master' into asset-metadata 2020-11-12 23:37:22 +01:00
49cc1f1718 Merge branch 'master' into asset-metadata 2020-10-30 15:00:56 +01:00
2137c15ef1 Merge branch 'master' into asset-metadata 2020-10-29 17:43:06 +01:00
0713427138 Merge branch 'master' into asset-metadata 2020-10-22 13:12:52 +02:00
a03e7ae90a Fix compile error after last merge 2020-10-07 19:17:28 +02:00
91f7d3e912 Merge branch 'master' into asset-metadata 2020-10-07 19:16:38 +02:00
c23e8edc54 Merge branch 'master' into asset-metadata 2020-09-29 12:54:49 +02:00
95946117ff Fix mistake in previous commit
The "Make Asset" button in context menus wouldn't actually do anything.
2020-09-23 15:02:09 +02:00
f4bbec1bcd Show "Make Asset" in the context menu of buttons showing IDs 2020-09-23 11:55:31 +02:00
5907daf73a Fix build error after latest merge 2020-09-22 17:47:34 +02:00
2b1345d347 Merge branch 'master' into asset-metadata 2020-09-22 17:33:30 +02:00
67da49df4d Merge branch 'master' into asset-metadata 2020-09-17 12:50:37 +02:00
cae97cde9c Fix compile error after last merge 2020-09-10 19:57:28 +02:00
bb51bc2a6d Merge branch 'master' into asset-metadata 2020-09-10 18:49:12 +02:00
d32aadab6e Adapt to new file read/write design from master
Partially a compile fix for previous commit. But also moving asset-data
read/write into `asset.c`, like we do it for more and more
data-structures in master.
2020-08-31 16:03:53 +02:00
6d317f24ec Merge branch 'master' into asset-metadata 2020-08-31 15:42:02 +02:00
4a8f6f59db Follow up to previous commit, rename asset operator in Outliner
Forgot to rename it in the Outliner as well ("Create Asset"->"Make
Asset").
2020-08-28 17:02:06 +02:00
a01fcfcc6a Keep assets local to the file, don't copy them
Previously my idea was that when creating an asset for the user
repository, we'd always create a deep copy of the data-block for storage
in the repository.
However for the initial design, we decided to not let Blender
automatically save things into a repository. The user has to mark a
data-block as asset and save the file, so the asset is stored as part of
that file. By adding a path to the Preferences, all .blend files in that
path become part of a repository and users can then access their assets
in different projects through the Asset Browser (not done yet).

Because of this, the operator is now called "Make Asset" again, not
"Create Asset". We don't create a new asset, we just add asset data to
an existing data-block.
2020-08-28 16:10:15 +02:00
ea48577e92 Merge branch 'master' into asset-metadata 2020-08-27 19:00:49 +02:00
0855126ee8 Updates for changes in master
Needed after last merge.
2020-08-24 20:07:23 +02:00
bd46a609b1 Merge branch 'master' into asset-metadata 2020-08-24 19:10:41 +02:00
8fc9c6e9f2 Merge branch 'master' into asset-metadata 2020-07-17 00:50:57 +02:00
022d0ab2f8 Add File Browser Link/Append option to show only assets 2020-07-10 16:57:29 +02:00
245a704b7c Support "Author" metadata field 2020-07-10 15:14:26 +02:00
38cf6e3634 Merge branch 'master' into asset-metadata 2020-07-10 11:37:48 +02:00
90d755bf21 Add access to asset-data from ID 2020-07-09 20:30:19 +02:00
42d75801de Remove asset data-block again, back to ID.asset_data design
So rather than having an asset data-block to reference data-blocks, let
the data-blocks reference asset-data.

After talking to Brecht, it seems that this approach is just fine. I previously
added the data-block type because I saw some benefits (faster & simpler asset
metadata reading, non-data-block assets, better file-browser integration,
simple remapping of referenced data-blocks), but there are ways to do the same
without the data-block. It's a bit more complicated that way, but still very
doable.
2020-07-09 20:19:39 +02:00
243a59ba6d Add custom tag support to assets
Tags are basically a list of strings. We could optimize these in future if
needed. We could also easily add colors or icons for individual tags (e.g. like
on developer.blender.org).

Note that there's no UI for this yet. Functionality is available via Python
though.
2020-07-08 21:41:29 +02:00
98ef119dcf Support arbitrary descriptions for assets
Simply have a dynamic string in the asset data-block. That can be set and
updated at any point.
2020-07-08 18:42:35 +02:00
b836dfd56c Support preview thumbnails for new asset data-blocks in file browser
Assets have to own a copy of the referenced data-block's preview for this to
work. We *could* do without that, but it complicates partial reading of
data-blocks for the file browser (which may be addressed with further work
though).
2020-07-08 16:36:00 +02:00
fff746f00a Use new Asset data-block type for "Create Asset" operator
AssetData is unused now. Just keeping it in case it's useful later (to avoid
having to do the monkey work to add it again).
2020-07-08 12:42:59 +02:00
10b55b3f5d Merge branch 'master' into asset-metadata 2020-07-08 11:01:22 +02:00
3417af0ebe Add new asset data-block type
With this we can read asset data in .blends more efficiently, e.g. for browsing
files or assets (where we avoid reading more than we have to). But there are
other things besides performance that I'd like to play with.
Basically I see the asset information a bit similar to library information,
which we also deal with as a separate data-block.

The "Create Asset" operator doesn't actually create these data-blocks yet.
That'll be added in a followup commit.

Of course this is not set in stone, but I think a reasonable design to work
with for now.
2020-07-06 15:41:08 +02:00
b2126c6a78 Merge branch 'master' into asset-metadata 2020-07-05 01:02:05 +02:00
02adf00d13 Fix crash when changing file after "Create Asset" 2020-07-04 15:16:09 +02:00
b8e592bd77 Support object preview thumbnails, generated on asset creation
To generate the preview, a temporary main data-base is created (think of this
as a virtual .blend within the current .blend) with a new scene and the object
to generate the preview for. It's rendered with a camera from the front, using
the "Camera Fit Frame to Selected" logic.
This should be a simple solution requiring no further setup that should work in
most cases. If needed we can have a way to set up the preview differently.

To see it in action:
* In the Outliner context menu for an object run ID Data > Create Asset
* Save the file
* Open a different file (so you can browse into the former)
* Use link/append to navigate into the saved file with the assets. You should
  see the preview in thumbnail mode.
2020-07-04 15:06:58 +02:00
bcb56f09c9 Show info report on successful asset creation
Also set fake-user for new asset data-block so it's not purged when closing the
file.
2020-07-04 15:04:58 +02:00
37741c8ef0 Rename "Make Asset" to "Create Asset"
The term "make" in this context refers to modifying an item to obtain a certain
property. Creating an asset however means saving a copy of a data-block as
asset. So "create" is better suited here.
2020-07-04 14:49:20 +02:00
18c431b3a8 Generate preview when making a data-block an asset 2020-07-02 18:17:15 +02:00
5760dc3da5 Initial "Make Asset" operator
Accessible via the Outliner context menu (ID Data submenu).

The operator currently copies the data-block and creates empty asset data for
it. This will later contain all the meta-data to "give the data-block meaning".

Of course there are many TODOs and questions remaining. This is the first step
so I can work more on meta-data support.
I created some files and that I think make sense.
2020-07-01 20:30:13 +02:00
48 changed files with 1027 additions and 48 deletions

View File

@@ -121,6 +121,10 @@
* \ingroup editors
*/
/** \defgroup edasset asset
* \ingroup editors
*/
/** \defgroup edcurve curve
* \ingroup editors
*/

View File

@@ -144,6 +144,9 @@ class FILEBROWSER_PT_filter(Panel):
row.label(icon='BLANK1') # Indentation
sub = row.column(align=True)
sub.prop(params, "use_filter_asset_only")
filter_id = params.filter_id
for identifier in dir(filter_id):
if identifier.startswith("category_"):
@@ -314,6 +317,9 @@ class FILEBROWSER_PT_advanced_filter(Panel):
if params.use_filter_blendid:
layout.separator()
col = layout.column(align=True)
col.prop(params, "use_filter_asset_only")
filter_id = params.filter_id
for identifier in dir(filter_id):
if identifier.startswith("filter_"):

View File

@@ -23,6 +23,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_action_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_anim_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_armature_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_asset_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_boid_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_brush_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_cachefile_types.h

View File

@@ -0,0 +1,53 @@
/*
* 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.
*/
#ifndef __BKE_ASSET_H__
#define __BKE_ASSET_H__
/** \file
* \ingroup bke
*/
#include "BLI_utildefines.h"
#ifdef __cplusplus
extern "C" {
#endif
struct BlendWriter;
struct BlendDataReader;
struct AssetData *BKE_asset_data_create(void);
void BKE_asset_data_free(struct AssetData *asset_data);
struct CustomTagEnsureResult {
struct CustomTag *tag;
/* Set to false if a tag of this name was already present. */
bool is_new;
};
struct CustomTagEnsureResult BKE_assetdata_tag_ensure(struct AssetData *asset_data,
const char *name);
void BKE_assetdata_tag_remove(struct AssetData *asset_data, struct CustomTag *tag);
void BKE_assetdata_write(struct BlendWriter *writer, struct AssetData *asset_data);
void BKE_assetdata_read(struct BlendDataReader *reader, struct AssetData *asset_data);
#ifdef __cplusplus
}
#endif
#endif /* __BKE_ASSET_H__ */

View File

@@ -129,6 +129,7 @@ void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size)
/* get the preview from any pointer */
struct PreviewImage **BKE_previewimg_id_get_p(const struct ID *id);
struct PreviewImage *BKE_previewimg_id_get(const struct ID *id);
/* free the preview image belonging to the id */
void BKE_previewimg_id_free(struct ID *id);

View File

@@ -77,6 +77,7 @@ set(SRC
intern/armature.c
intern/armature_deform.c
intern/armature_update.c
intern/asset.c
intern/attribute.c
intern/autoexec.c
intern/blender.c
@@ -267,6 +268,7 @@ set(SRC
BKE_armature.h
BKE_attribute.h
BKE_autoexec.h
BKE_asset.h
BKE_blender.h
BKE_blender_copybuffer.h
BKE_blender_undo.h

View File

@@ -0,0 +1,116 @@
/*
* 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.
*/
/** \file
* \ingroup bke
*/
#include <string.h>
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_asset.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "DNA_ID.h"
#include "DNA_asset_types.h"
#include "DNA_defaults.h"
#include "BLO_read_write.h"
#include "MEM_guardedalloc.h"
AssetData *BKE_asset_data_create(void)
{
AssetData *asset_data = MEM_callocN(sizeof(AssetData), __func__);
memcpy(asset_data, DNA_struct_default_get(AssetData), sizeof(*asset_data));
return asset_data;
}
void BKE_asset_data_free(AssetData *asset_data)
{
if (asset_data->properties) {
IDP_FreeProperty(asset_data->properties);
}
MEM_SAFE_FREE(asset_data->description);
BLI_freelistN(&asset_data->tags);
MEM_SAFE_FREE(asset_data);
}
struct CustomTagEnsureResult BKE_assetdata_tag_ensure(AssetData *asset_data, const char *name)
{
struct CustomTagEnsureResult result = {.tag = NULL};
if (!name[0]) {
return result;
}
CustomTag *tag = BLI_findstring(&asset_data->tags, name, offsetof(CustomTag, name));
if (tag) {
result.tag = tag;
result.is_new = false;
return result;
}
tag = MEM_mallocN(sizeof(*tag), __func__);
BLI_strncpy(tag->name, name, sizeof(tag->name));
BLI_addtail(&asset_data->tags, tag);
result.tag = tag;
result.is_new = true;
return result;
}
void BKE_assetdata_tag_remove(AssetData *asset_data, CustomTag *tag)
{
BLI_freelinkN(&asset_data->tags, tag);
}
/* .blend file API -------------------------------------------- */
void BKE_assetdata_write(BlendWriter *writer, AssetData *asset_data)
{
BLO_write_struct(writer, AssetData, asset_data);
if (asset_data->properties) {
IDP_BlendWrite(writer, asset_data->properties);
}
if (asset_data->description) {
BLO_write_string(writer, asset_data->description);
}
LISTBASE_FOREACH (CustomTag *, tag, &asset_data->tags) {
BLO_write_struct(writer, CustomTag, tag);
}
}
void BKE_assetdata_read(BlendDataReader *reader, AssetData *asset_data)
{
/* asset_data itself has been read already. */
if (asset_data->properties) {
BLO_read_data_address(reader, &asset_data->properties);
IDP_BlendDataRead(reader, &asset_data->properties);
}
BLO_read_data_address(reader, &asset_data->description);
BLO_read_list(reader, &asset_data->tags);
}

View File

@@ -342,6 +342,12 @@ PreviewImage **BKE_previewimg_id_get_p(const ID *id)
return NULL;
}
PreviewImage *BKE_previewimg_id_get(const ID *id)
{
PreviewImage **prv_p = BKE_previewimg_id_get_p(id);
return prv_p ? *prv_p : NULL;
}
void BKE_previewimg_id_free(ID *id)
{
PreviewImage **prv_p = BKE_previewimg_id_get_p(id);

View File

@@ -55,6 +55,7 @@
#include "BKE_anim_data.h"
#include "BKE_armature.h"
#include "BKE_asset.h"
#include "BKE_bpath.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -2361,6 +2362,10 @@ void BKE_id_reorder(const ListBase *lb, ID *id, ID *relative, bool after)
void BKE_id_blend_write(BlendWriter *writer, ID *id)
{
if (id->asset_data) {
BKE_assetdata_write(writer, id->asset_data);
}
/* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
if (id->properties && !ELEM(GS(id->name), ID_WM)) {
IDP_BlendWrite(writer, id->properties);

View File

@@ -31,6 +31,7 @@
#include "BLI_listbase.h"
#include "BKE_anim_data.h"
#include "BKE_asset.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_key.h"
@@ -64,6 +65,10 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
id->override_library = NULL;
}
if (id->asset_data) {
BKE_asset_data_free(id->asset_data);
}
BKE_animdata_free(id, do_id_user);
}

View File

@@ -119,12 +119,20 @@ void BLO_blendfiledata_free(BlendFileData *bfd);
/** \name BLO Blend File Handle API
* \{ */
struct BLODataBlockInfo {
char name[64]; /* MAX_NAME */
bool is_asset;
};
BlendHandle *BLO_blendhandle_from_file(const char *filepath, struct ReportList *reports);
BlendHandle *BLO_blendhandle_from_memory(const void *mem, int memsize);
struct LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh,
int ofblocktype,
int *tot_names);
struct LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
int ofblocktype,
int *tot_names);
struct LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *tot_prev);
struct LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh);

View File

@@ -159,6 +159,42 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
return names;
}
/**
* Gets the names of all the data-blocks in a file of a certain type
* (e.g. all the scene names in a file).
*
* \param bh: The blendhandle to access.
* \param ofblocktype: The type of names to get.
* \param tot_names: The length of the returned list.
* \return A BLI_linklist of BLODataBlockInfo *. The links should be freed with MEM_freeN.
*/
LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh, int ofblocktype, int *tot_names)
{
FileData *fd = (FileData *)bh;
LinkNode *infos = NULL;
BHead *bhead;
int tot = 0;
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == ofblocktype) {
struct BLODataBlockInfo *info = MEM_mallocN(sizeof(*info), __func__);
const char *name = blo_bhead_id_name(fd, bhead) + 2;
STRNCPY(info->name, name);
info->is_asset = blo_bhead_id_asset_data(fd, bhead) != NULL;
BLI_linklist_prepend(&infos, info);
tot++;
}
else if (bhead->code == ENDB) {
break;
}
}
*tot_names = tot;
return infos;
}
/**
* Gets the previews of all the data-blocks in a file of a certain type
* (e.g. all the scene previews in a file).
@@ -254,7 +290,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
* (e.g. "Scene", "Mesh", "Light", etc.).
*
* \param bh: The blendhandle to access.
* \return A BLI_linklist of strings. The string links should be freed with malloc.
* \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN().
*/
LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
{
@@ -272,7 +308,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
const char *str = BKE_idtype_idcode_to_name(bhead->code);
if (BLI_gset_add(gathered, (void *)str)) {
BLI_linklist_prepend(&names, strdup(str));
BLI_linklist_prepend(&names, BLI_strdup(str));
}
}
}

View File

@@ -44,6 +44,9 @@
#define DNA_DEPRECATED_ALLOW
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_asset_types.h"
#include "DNA_brush_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_fileglobal_types.h"
#include "DNA_genfile.h"
@@ -71,6 +74,9 @@
#include "BKE_anim_data.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_asset.h"
#include "BKE_brush.h"
#include "BKE_collection.h"
#include "BKE_global.h" /* for G */
#include "BKE_idprop.h"
@@ -961,6 +967,14 @@ const char *blo_bhead_id_name(const FileData *fd, const BHead *bhead)
return (const char *)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_name_offs);
}
/* Warning! Caller's responsibility to ensure given bhead **is** and ID one! */
AssetData *blo_bhead_id_asset_data(const FileData *fd, const BHead *bhead)
{
return (fd->id_asset_data_offs > 0) ?
*(AssetData **)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_asset_data_offs) :
NULL;
}
static void decode_blender_header(FileData *fd)
{
char header[SIZEOFBLENDERHEADER], num[4];
@@ -1038,6 +1052,7 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
/* used to retrieve ID names from (bhead+1) */
fd->id_name_offs = DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
BLI_assert(fd->id_name_offs != -1);
fd->id_asset_data_offs = DNA_elem_offset(fd->filesdna, "ID", "AssetData", "*asset_data");
return true;
}
@@ -2358,6 +2373,11 @@ static void direct_link_id_common(
return;
}
if (id->asset_data) {
BLO_read_data_address(reader, &id->asset_data);
BKE_assetdata_read(reader, id->asset_data);
}
/*link direct data of ID properties*/
if (id->properties) {
BLO_read_data_address(reader, &id->properties);

View File

@@ -112,6 +112,9 @@ typedef struct FileData {
int fileversion;
/** Used to retrieve ID names from (bhead+1). */
int id_name_offs;
/** Used to retrieve asset data from (bhead+1). NOTE: This may not be available in old files,
* will be 0 then! */
int id_asset_data_offs;
/** For do_versions patching. */
int globalf, fileflags;
@@ -170,6 +173,7 @@ BHead *blo_bhead_next(FileData *fd, BHead *thisblock);
BHead *blo_bhead_prev(FileData *fd, BHead *thisblock);
const char *blo_bhead_id_name(const FileData *fd, const BHead *bhead);
struct AssetData *blo_bhead_id_asset_data(const FileData *fd, const BHead *bhead);
/* do versions stuff */

View File

@@ -93,6 +93,7 @@
/* allow writefile to use deprecated functionality (for forward compatibility code) */
#define DNA_DEPRECATED_ALLOW
#include "DNA_asset_types.h"
#include "DNA_fileglobal_types.h"
#include "DNA_genfile.h"
#include "DNA_sdna_types.h"

View File

@@ -22,6 +22,7 @@ if(WITH_BLENDER)
add_subdirectory(animation)
add_subdirectory(armature)
add_subdirectory(asset)
add_subdirectory(curve)
add_subdirectory(geometry)
add_subdirectory(gizmo_library)

View File

@@ -0,0 +1,37 @@
# ***** 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.
# ***** END GPL LICENSE BLOCK *****
set(INC
../include
../../blenlib
../../blenkernel
../../makesdna
../../makesrna
../../windowmanager
)
set(INC_SYS
)
set(SRC
asset_ops.c
)
set(LIB
)
blender_add_lib(bf_editor_asset "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@@ -0,0 +1,87 @@
/*
* 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.
*/
/** \file
* \ingroup edasset
*/
#include "BKE_asset.h"
#include "BKE_context.h"
#include "BKE_icons.h"
#include "BKE_lib_id.h"
#include "BKE_report.h"
#include "DNA_asset_types.h"
#include "ED_asset.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "UI_interface_icons.h"
#include "WM_api.h"
#include "WM_types.h"
static int asset_make_exec(bContext *C, wmOperator *op)
{
PointerRNA idptr = RNA_pointer_get(op->ptr, "id");
ID *id = idptr.data;
if (!id || !RNA_struct_is_ID(idptr.type)) {
return OPERATOR_CANCELLED;
}
if (id->asset_data) {
BKE_reportf(op->reports, RPT_ERROR, "Data-block '%s' already is an asset", id->name + 2);
return OPERATOR_CANCELLED;
}
/* TODO this should probably be somewhere in BKE and/or ED. */
id_fake_user_set(id);
id->asset_data = BKE_asset_data_create();
UI_icon_render_id(C, NULL, id, true, false);
/* Store reference to the ID's preview. */
id->asset_data->preview = BKE_previewimg_id_get(id);
BKE_reportf(op->reports, RPT_INFO, "Data-block '%s' is now an asset", id->name + 2);
WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
static void ASSET_OT_make(wmOperatorType *ot)
{
ot->name = "Make Asset";
ot->description = "Enable asset management for a data-block";
ot->idname = "ASSET_OT_make";
ot->exec = asset_make_exec;
RNA_def_pointer_runtime(
ot->srna, "id", &RNA_ID, "Data-block", "Data-block to enable asset management for");
}
/* -------------------------------------------------------------------- */
void ED_operatortypes_asset(void)
{
WM_operatortype_append(ASSET_OT_make);
}

View File

@@ -0,0 +1,34 @@
/*
* 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.
*/
/** \file
* \ingroup editors
*/
#ifndef __ED_ASSET_H__
#define __ED_ASSET_H__
#ifdef __cplusplus
extern "C" {
#endif
void ED_operatortypes_asset(void);
#ifdef __cplusplus
}
#endif
#endif /* __ED_ASSET_H__ */

View File

@@ -141,6 +141,11 @@ void ED_view3d_to_object(const struct Depsgraph *depsgraph,
const float quat[4],
const float dist);
bool ED_view3d_camera_to_view_selected(struct Main *bmain,
struct Depsgraph *depsgraph,
const struct Scene *scene,
struct Object *camera_ob);
void ED_view3d_lastview_store(struct RegionView3D *rv3d);
/* Depth buffer */

View File

@@ -957,6 +957,15 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
ui_but_menu_add_path_operators(layout, ptr, prop);
uiItemS(layout);
}
if (RNA_struct_is_ID(but->rnapoin.type)) {
PointerRNA op_ptr;
uiItemFullO(
layout, "ASSET_OT_make", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
RNA_pointer_set(&op_ptr, "id", but->rnapoin);
uiItemS(layout);
}
}
/* Pointer properties and string properties with

View File

@@ -1964,12 +1964,7 @@ static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)
}
for (enum eIconSizes i = 0; i < NUM_ICON_SIZES; i++) {
/* check if rect needs to be created; changed
* only set by dynamic icons */
if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
icon_set_image(C, NULL, id, pi, i, use_jobs);
pi->flag[i] &= ~PRV_CHANGED;
}
ui_id_preview_image_render_size(C, NULL, id, pi, i, use_jobs);
}
}

View File

@@ -68,6 +68,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
#include "BKE_world.h"
@@ -94,12 +95,16 @@
#include "ED_datafiles.h"
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_view3d.h"
#include "ED_view3d_offscreen.h"
#ifndef NDEBUG
/* Used for database init assert(). */
# include "BLI_threads.h"
#endif
void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect);
ImBuf *get_brush_icon(Brush *brush)
{
static const int flags = IB_rect | IB_multilayer | IB_metadata;
@@ -336,7 +341,7 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world)
return sp->worldcopy;
}
static ID *duplicate_ids(ID *id)
static ID *duplicate_ids(ID *id, bool allow_failure)
{
if (id == NULL) {
/* Non-ID preview render. */
@@ -357,7 +362,9 @@ static ID *duplicate_ids(ID *id)
case ID_SCR:
return NULL;
default:
BLI_assert(!"ID type preview not supported.");
if (!allow_failure) {
BLI_assert(!"ID type preview not supported.");
}
return NULL;
}
}
@@ -698,6 +705,131 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
}
}
/* **************************** Object preview ****************** */
struct ObjectPreviewData {
/* The main for the preview, not of the current file. */
Main *main;
/* The original object to create the preview for. */
Object *object;
int sizex;
int sizey;
};
static Object *object_preview_camera_create(
Main *preview_main, ViewLayer *view_layer, Object *preview_object, int sizex, int sizey)
{
Object *camera = BKE_object_add(preview_main, view_layer, OB_CAMERA, "Preview Camera");
float rotmat[3][3];
float dummyscale[3];
mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->obmat);
/* Camera is Y up, so needs additional 90deg rotation around X to match object's Z up. */
float drotmat[3][3];
axis_angle_to_mat3_single(drotmat, 'X', M_PI_2);
mul_m3_m3_post(rotmat, drotmat);
camera->rotmode = ROT_MODE_QUAT;
mat3_to_quat(camera->quat, rotmat);
/* shader_preview_render() does this too. */
if (sizex > sizey) {
((Camera *)camera->data)->lens *= (float)sizey / (float)sizex;
}
return camera;
}
static Scene *object_preview_scene_create(const struct ObjectPreviewData *preview_data,
Depsgraph **r_depsgraph)
{
Scene *scene = BKE_scene_add(preview_data->main, "Object preview scene");
ViewLayer *view_layer = scene->view_layers.first;
Depsgraph *depsgraph = DEG_graph_new(preview_data->main, scene, view_layer, DAG_EVAL_VIEWPORT);
/* FIXME For now just create a copy of the object for the new main, until we have a better way to
* obtain the ID in a different Main (i.e. read from asset file). */
Object *preview_object_copy = (Object *)BKE_id_copy(preview_data->main,
&preview_data->object->id);
if (!preview_object_copy) {
BLI_assert(false);
return NULL;
}
BKE_collection_object_add(preview_data->main, scene->master_collection, preview_object_copy);
Object *camera_object = object_preview_camera_create(preview_data->main,
view_layer,
preview_object_copy,
preview_data->sizex,
preview_data->sizey);
scene->camera = camera_object;
scene->r.xsch = preview_data->sizex;
scene->r.ysch = preview_data->sizey;
scene->r.size = 100;
Base *preview_base = BKE_view_layer_base_find(view_layer, preview_object_copy);
/* For 'view selected' below. */
preview_base->flag |= BASE_SELECTED;
DEG_graph_build_from_view_layer(depsgraph);
DEG_evaluate_on_refresh(depsgraph);
ED_view3d_camera_to_view_selected(preview_data->main, depsgraph, scene, camera_object);
BKE_scene_graph_update_tagged(depsgraph, preview_data->main);
*r_depsgraph = depsgraph;
return scene;
}
static void object_preview_render(IconPreview *preview, IconPreviewSize *preview_sized)
{
Main *preview_main = BKE_main_new();
const float pixelsize_old = U.pixelsize;
char err_out[256] = "unknown";
struct ObjectPreviewData preview_data = {
.main = preview_main,
.object = (Object *)preview->id,
.sizex = preview_sized->sizex,
.sizey = preview_sized->sizey,
};
Depsgraph *depsgraph;
Scene *scene = object_preview_scene_create(&preview_data, &depsgraph);
U.pixelsize = 2.0f;
ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple(
depsgraph,
DEG_get_evaluated_scene(depsgraph),
NULL,
OB_SOLID,
DEG_get_evaluated_object(depsgraph, scene->camera),
preview_sized->sizex,
preview_sized->sizey,
IB_rect,
V3D_OFSDRAW_NONE,
R_ALPHAPREMUL,
NULL,
NULL,
err_out);
/* TODO color-management? */
U.pixelsize = pixelsize_old;
if (ibuf) {
icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect);
IMB_freeImBuf(ibuf);
}
DEG_graph_free(depsgraph);
BKE_main_free(preview_main);
}
/* **************************** new shader preview system ****************** */
/* inside thread, called by renderer, sets job update value */
@@ -1011,7 +1143,7 @@ static void shader_preview_free(void *customdata)
/* ************************* icon preview ********************** */
static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
{
struct ImBuf *ima;
uint *drect, *srect;
@@ -1235,6 +1367,11 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
if (ELEM(GS(ip->id->name), ID_OB)) {
object_preview_render(ip, cur_size);
continue;
}
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
const bool is_render = !(prv->tag & PRV_TAG_DEFFERED);
@@ -1333,7 +1470,9 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, uint *rect, int s
ip.scene = scene;
ip.owner = BKE_previewimg_id_ensure(id);
ip.id = id;
ip.id_copy = duplicate_ids(id);
/* Control isn't given back to the caller until the preview is done. So we don't need to copy
* the ID to avoid thread races. */
ip.id_copy = duplicate_ids(id, true);
icon_preview_add_size(&ip, rect, sizex, sizey);
@@ -1376,7 +1515,7 @@ void ED_preview_icon_job(
ip->scene = CTX_data_scene(C);
ip->owner = owner;
ip->id = id;
ip->id_copy = duplicate_ids(id);
ip->id_copy = duplicate_ids(id, false);
icon_preview_add_size(ip, rect, sizex, sizey);
@@ -1445,7 +1584,7 @@ void ED_preview_shader_job(const bContext *C,
sp->sizey = sizey;
sp->pr_method = method;
sp->id = id;
sp->id_copy = duplicate_ids(id);
sp->id_copy = duplicate_ids(id, false);
sp->own_id_copy = true;
sp->parent = parent;
sp->slot = slot;

View File

@@ -40,6 +40,7 @@
#include "ED_anim_api.h"
#include "ED_armature.h"
#include "ED_asset.h"
#include "ED_clip.h"
#include "ED_curve.h"
#include "ED_fileselect.h"
@@ -105,6 +106,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_screen();
ED_operatortypes_anim();
ED_operatortypes_animchannels();
ED_operatortypes_asset();
ED_operatortypes_gpencil();
ED_operatortypes_object();
ED_operatortypes_lattice();

View File

@@ -208,6 +208,8 @@ typedef struct FileListInternEntry {
int typeflag;
/** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
int blentype;
/** Tag for assets, in case typeflag has FILE_TYPE_BLENDERLIB set. */
bool is_asset;
char *relpath;
/** Optional argument for shortcuts, aliases etc. */
@@ -289,6 +291,7 @@ enum {
FLF_HIDE_DOT = 1 << 1,
FLF_HIDE_PARENT = 1 << 2,
FLF_HIDE_LIB_DIR = 1 << 3,
FLF_ASSETS_ONLY = 1 << 4,
};
typedef struct FileList {
@@ -693,6 +696,9 @@ static bool is_filtered_hidden(const char *filename,
return true;
}
#endif
if ((filter->flags & FLF_ASSETS_ONLY) && !file->is_asset) {
return true;
}
return false;
}
@@ -857,6 +863,7 @@ void filelist_setfilter_options(FileList *filelist,
const bool hide_parent,
const uint64_t filter,
const uint64_t filter_id,
const bool filter_assets_only,
const char *filter_glob,
const char *filter_search)
{
@@ -874,6 +881,10 @@ void filelist_setfilter_options(FileList *filelist,
filelist->filter_data.flags ^= FLF_HIDE_PARENT;
update = true;
}
if (((filelist->filter_data.flags & FLF_ASSETS_ONLY) != 0) != (filter_assets_only != 0)) {
filelist->filter_data.flags ^= FLF_ASSETS_ONLY;
update = true;
}
if (filelist->filter_data.filter != filter) {
filelist->filter_data.filter = filter;
update = true;
@@ -2563,8 +2574,8 @@ static int filelist_readjob_list_dir(const char *root,
static int filelist_readjob_list_lib(const char *root, ListBase *entries, const bool skip_currpar)
{
FileListInternEntry *entry;
LinkNode *ln, *names;
int i, nnames, idcode = 0, nbr_entries = 0;
LinkNode *ln, *names, *datablock_infos = NULL;
int i, nitems, idcode = 0, nbr_entries = 0;
char dir[FILE_MAX_LIBEXTRA], *group;
bool ok;
@@ -2586,11 +2597,11 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
* and freed in filelist_entry_free. */
if (group) {
idcode = groupname_to_code(group);
names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames);
datablock_infos = BLO_blendhandle_get_datablock_info(libfiledata, idcode, &nitems);
}
else {
names = BLO_blendhandle_get_linkable_groups(libfiledata);
nnames = BLI_linklist_count(names);
nitems = BLI_linklist_count(names);
}
BLO_blendhandle_close(libfiledata);
@@ -2603,12 +2614,14 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
nbr_entries++;
}
for (i = 0, ln = names; i < nnames; i++, ln = ln->next) {
const char *blockname = ln->link;
for (i = 0, ln = (datablock_infos ? datablock_infos : names); i < nitems; i++, ln = ln->next) {
struct BLODataBlockInfo *info = datablock_infos ? ln->link : NULL;
const char *blockname = info ? info->name : ln->link;
entry = MEM_callocN(sizeof(*entry), __func__);
entry->relpath = BLI_strdup(blockname);
entry->typeflag |= FILE_TYPE_BLENDERLIB;
entry->is_asset = info && info->is_asset;
if (!(group && idcode)) {
entry->typeflag |= FILE_TYPE_DIR;
entry->blentype = groupname_to_code(blockname);
@@ -2620,7 +2633,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
nbr_entries++;
}
BLI_linklist_free(names, free);
BLI_linklist_free(datablock_infos ? datablock_infos : names, MEM_freeN);
return nbr_entries;
}

View File

@@ -63,6 +63,7 @@ void filelist_setfilter_options(struct FileList *filelist,
const bool hide_parent,
const uint64_t filter,
const uint64_t filter_id,
const bool filter_assets_only,
const char *filter_glob,
const char *filter_search);
void filelist_filter(struct FileList *filelist);

View File

@@ -290,6 +290,7 @@ static void file_refresh(const bContext *C, ScrArea *area)
true, /* Just always hide parent, prefer to not add an extra user option for this. */
params->filter,
params->filter_id,
(params->flag & FILE_ASSETS_ONLY) != 0,
params->filter_glob,
params->filter_search);

View File

@@ -712,6 +712,27 @@ static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *s
}
}
static void id_make_asset_cb(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep),
TreeStoreElem *tselem,
void *UNUSED(user_data))
{
ID *id = tselem->id;
PointerRNA id_ptr;
PointerRNA op_ptr;
RNA_id_pointer_create(id, &id_ptr);
WM_operator_properties_create(&op_ptr, "ASSET_OT_make");
RNA_pointer_set(&op_ptr, "id", id_ptr);
WM_operator_name_call(C, "ASSET_OT_make", WM_OP_EXEC_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
}
static void id_local_fn(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
@@ -1685,6 +1706,7 @@ typedef enum eOutlinerIdOpTypes {
OUTLINER_IDOP_INVALID = 0,
OUTLINER_IDOP_UNLINK,
OUTLINER_IDOP_MAKE_ASSET,
OUTLINER_IDOP_LOCAL,
OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE,
OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY,
@@ -1710,6 +1732,7 @@ typedef enum eOutlinerIdOpTypes {
/* TODO: implement support for changing the ID-block used. */
static const EnumPropertyItem prop_id_op_types[] = {
{OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
{OUTLINER_IDOP_MAKE_ASSET, "MAKE_ASSET", 0, "Make Asset", ""},
{OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
{OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
@@ -1915,6 +1938,14 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
}
break;
}
case OUTLINER_IDOP_MAKE_ASSET: {
outliner_do_libdata_operation(
C, op->reports, scene, space_outliner, &space_outliner->tree, id_make_asset_cb, NULL);
ED_undo_push(C, "Made Asset");
/* TODO how to handle undo here? id_make_asset_cb() calls an OP. Esp. in case of multiple
* data-blocks we only want a single push. */
break;
}
case OUTLINER_IDOP_LOCAL: {
/* make local */
outliner_do_libdata_operation(

View File

@@ -1622,6 +1622,41 @@ void ED_view3d_to_object(const Depsgraph *depsgraph,
BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
}
bool ED_view3d_camera_to_view_selected(struct Main *bmain,
Depsgraph *depsgraph,
const Scene *scene,
Object *camera_ob)
{
Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
float co[3]; /* the new location to apply */
float scale; /* only for ortho cameras */
if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, co, &scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
if ((camera_ob_eval->type == OB_CAMERA) &&
(((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
((Camera *)camera_ob->data)->ortho_scale = scale;
}
copy_m4_m4(obmat_new, camera_ob_eval->obmat);
copy_v3_v3(obmat_new[3], co);
/* only touch location */
BKE_object_tfm_protected_backup(camera_ob, &obtfm);
BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
/* notifiers */
DEG_id_tag_update_ex(bmain, &camera_ob->id, ID_RECALC_TRANSFORM);
return true;
}
return false;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@@ -535,40 +535,18 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
* meant to take into account vertex/bone selection for eg. */
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
Object *camera_ob = v3d ? v3d->camera : scene->camera;
Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
float r_co[3]; /* the new location to apply */
float r_scale; /* only for ortho cameras */
if (camera_ob_eval == NULL) {
if (camera_ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active camera");
return OPERATOR_CANCELLED;
}
/* this function does all the important stuff */
if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
if ((camera_ob_eval->type == OB_CAMERA) &&
(((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
((Camera *)camera_ob->data)->ortho_scale = r_scale;
}
copy_m4_m4(obmat_new, camera_ob_eval->obmat);
copy_v3_v3(obmat_new[3], r_co);
/* only touch location */
BKE_object_tfm_protected_backup(camera_ob, &obtfm);
BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
/* notifiers */
DEG_id_tag_update(&camera_ob->id, ID_RECALC_TRANSFORM);
if (ED_view3d_camera_to_view_selected(bmain, depsgraph, scene, camera_ob)) {
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob);
return OPERATOR_FINISHED;
}

View File

@@ -47,6 +47,7 @@ set(SRC
../include/BIF_glutil.h
../include/ED_anim_api.h
../include/ED_armature.h
../include/ED_asset.h
../include/ED_buttons.h
../include/ED_clip.h
../include/ED_curve.h

View File

@@ -264,7 +264,14 @@ typedef struct IDOverrideLibrary {
typedef struct ID {
void *next, *prev;
struct ID *newid;
struct Library *lib;
/** If this ID is an asset, this pointer is set and references all data defining an asset. */
/* TODO this will probably not stay here. Instead we might want a new asset ID-type that
* references another ID. */
struct AssetData *asset_data;
/** MAX_ID_NAME. */
char name[66];
/**

View File

@@ -0,0 +1,39 @@
/*
* 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.
*/
/** \file
* \ingroup DNA
*/
#ifndef __DNA_ASSET_DEFAULTS_H__
#define __DNA_ASSET_DEFAULTS_H__
/* Struct members on own line. */
/* clang-format off */
/* -------------------------------------------------------------------- */
/** \name Asset Struct
* \{ */
#define _DNA_DEFAULT_AssetData \
{ \
}
/** \} */
/* clang-format on */
#endif /* __DNA_ASSET_DEFAULTS_H__ */

View File

@@ -0,0 +1,61 @@
/*
* 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.
*/
/** \file
* \ingroup DNA
*/
#ifndef __DNA_ASSET_TYPES_H__
#define __DNA_ASSET_TYPES_H__
#include "DNA_listBase.h"
/**
* \brief User defined tag.
* Currently only used by assets, could be used more often at some point.
* Maybe add a custom icon and color to these in future?
*/
typedef struct CustomTag {
struct CustomTag *next, *prev;
char name[64]; /* MAX_NAME */
} CustomTag;
/**
* \brief The meta-data of an asset.
* By creating and giving this for a data-block (#ID.asset_data), the data-block becomes an asset.
*
* \note This struct must be readable without having to read anything but blocks from the ID it is
* attached to! That way, asset information of a file can be read, without reading anything
* more than that from the file. So pointers to other IDs or ID data are strictly forbidden.
*/
typedef struct AssetData {
/** Thumbnail image of the data-block. Duplicate of the referenced ID preview. */
struct PreviewImage *preview;
/** Custom asset meta-data. Cannot store pointers to IDs (#STRUCT_NO_DATABLOCK_IDPROPERTIES)! */
struct IDProperty *properties;
/** Optional description of this asset for display in the UI. Dynamic length. */
char *description;
/** Optional name of the person that created this asset. */
char author[64]; /* MAX_NAME */
/** User defined tags for this asset. The asset manager uses these for filtering, but how they
* function exactly (e.g. how they are registered to provide a list of searchable available tags)
* is up to the asset-engine. */
ListBase tags; /* CustomTag */
} AssetData;
#endif /* __DNA_ASSET_TYPES_H__ */

View File

@@ -845,6 +845,7 @@ typedef enum eFileSel_Params_Flag {
FILE_SORT_INVERT = (1 << 11),
FILE_HIDE_TOOL_PROPS = (1 << 12),
FILE_CHECK_EXISTING = (1 << 13),
FILE_ASSETS_ONLY = (1 << 14),
} eFileSel_Params_Flag;
/* sfile->params->rename_flag */

View File

@@ -61,6 +61,7 @@ typedef struct Text {
int flags;
char _pad0[4];
void *_pad1;
ListBase lines;
TextLine *curl, *sell;

View File

@@ -138,6 +138,7 @@ set(SRC
../../blenlib/intern/hash_mm2a.c
../../blenlib/intern/listbase.c
../DNA_asset_defaults.h
../DNA_brush_defaults.h
../DNA_cachefile_defaults.h
../DNA_camera_defaults.h

View File

@@ -85,6 +85,7 @@
#include "DNA_defaults.h"
#include "DNA_armature_types.h"
#include "DNA_asset_types.h"
#include "DNA_brush_types.h"
#include "DNA_cachefile_types.h"
#include "DNA_camera_types.h"
@@ -117,6 +118,7 @@
#include "DNA_world_types.h"
#include "DNA_armature_defaults.h"
#include "DNA_asset_defaults.h"
#include "DNA_brush_defaults.h"
#include "DNA_cachefile_defaults.h"
#include "DNA_camera_defaults.h"
@@ -148,6 +150,9 @@
#define SDNA_DEFAULT_DECL_STRUCT(struct_name) \
static const struct_name DNA_DEFAULT_##struct_name = _DNA_DEFAULT_##struct_name
/* DNA_asset_defaults.h */
SDNA_DEFAULT_DECL_STRUCT(AssetData);
/* DNA_armature_defaults.h */
SDNA_DEFAULT_DECL_STRUCT(bArmature);
@@ -338,7 +343,10 @@ extern const bTheme U_theme_default;
/** Keep headers sorted. */
const void *DNA_default_table[SDNA_TYPE_MAX] = {
/* DNA_arnature_defaults.h */
/* DNA_asset_defaults.h */
SDNA_DEFAULT_DECL(AssetData),
/* DNA_armature_defaults.h */
SDNA_DEFAULT_DECL(bArmature),
/* DNA_brush_defaults.h */

View File

@@ -139,6 +139,7 @@ static const char *includefiles[] = {
"DNA_volume_types.h",
"DNA_simulation_types.h",
"DNA_pointcache_types.h",
"DNA_asset_types.h",
/* see comment above before editing! */
@@ -1533,6 +1534,7 @@ int main(int argc, char **argv)
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_asset_types.h"
#include "DNA_boid_types.h"
#include "DNA_brush_types.h"
#include "DNA_cachefile_types.h"

View File

@@ -69,6 +69,7 @@ extern StructRNA RNA_ArrayGpencilModifier;
extern StructRNA RNA_ArrayModifier;
extern StructRNA RNA_Attribute;
extern StructRNA RNA_AttributeGroup;
extern StructRNA RNA_AssetData;
extern StructRNA RNA_BackgroundImage;
extern StructRNA RNA_BevelModifier;
extern StructRNA RNA_BezierSplinePoint;
@@ -209,6 +210,7 @@ extern StructRNA RNA_CurveModifier;
extern StructRNA RNA_CurvePoint;
extern StructRNA RNA_CurveProfile;
extern StructRNA RNA_CurveProfilePoint;
extern StructRNA RNA_CustomTag;
extern StructRNA RNA_DampedTrackConstraint;
extern StructRNA RNA_DataTransferModifier;
extern StructRNA RNA_DecimateModifier;

View File

@@ -31,6 +31,7 @@ set(DEFSRC
rna_animviz.c
rna_armature.c
rna_attribute.c
rna_asset.c
rna_boid.c
rna_brush.c
rna_cachefile.c
@@ -426,6 +427,7 @@ set(LIB
bf_editor_animation
bf_editor_armature
bf_editor_asset
bf_editor_curve
bf_editor_gizmo_library
bf_editor_gpencil

View File

@@ -4270,6 +4270,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_animviz.c", NULL, RNA_def_animviz},
{"rna_armature.c", "rna_armature_api.c", RNA_def_armature},
{"rna_attribute.c", NULL, RNA_def_attribute},
{"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

@@ -1527,6 +1527,11 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Library", "Library file the data-block is linked from");
prop = RNA_def_property(srna, "asset_data", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Asset Data", "Additional data for an asset data-block");
prop = RNA_def_pointer(
srna, "override_library", "IDOverrideLibrary", "Library Override", "Library override data");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);

View File

@@ -0,0 +1,204 @@
/*
* 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.
*/
/** \file
* \ingroup RNA
*/
#include <stdlib.h>
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "DNA_asset_types.h"
#include "DNA_defs.h"
#include "rna_internal.h"
#ifdef RNA_RUNTIME
# include "BKE_asset.h"
# include "BKE_idprop.h"
# include "RNA_access.h"
static CustomTag *rna_AssetData_tag_new(AssetData *asset_data,
ReportList *reports,
const char *name)
{
struct CustomTagEnsureResult result = BKE_assetdata_tag_ensure(asset_data, name);
if (!result.is_new) {
BKE_reportf(
reports, RPT_WARNING, "Tag '%s' already present for given asset", result.tag->name);
/* Report, but still return valid item. */
}
return result.tag;
}
static void rna_AssetData_tag_remove(AssetData *asset_data,
ReportList *reports,
PointerRNA *tag_ptr)
{
CustomTag *tag = tag_ptr->data;
if (BLI_findindex(&asset_data->tags, tag) == -1) {
BKE_reportf(reports, RPT_ERROR, "Tag '%s' not found in given asset", tag->name);
return;
}
BKE_assetdata_tag_remove(asset_data, tag);
RNA_POINTER_INVALIDATE(tag_ptr);
}
static IDProperty *rna_AssetData_idprops(PointerRNA *ptr, bool create)
{
AssetData *asset_data = ptr->data;
if (create && !asset_data->properties) {
IDPropertyTemplate val = {0};
asset_data->properties = IDP_New(IDP_GROUP, &val, "RNA_AssetData group");
}
return asset_data->properties;
}
static void rna_AssetData_description_get(PointerRNA *ptr, char *value)
{
AssetData *asset_data = ptr->data;
if (asset_data->description) {
strcpy(value, asset_data->description);
}
else {
value[0] = '\0';
}
}
static int rna_AssetData_description_length(PointerRNA *ptr)
{
AssetData *asset_data = ptr->data;
return asset_data->description ? strlen(asset_data->description) : 0;
}
static void rna_AssetData_description_set(PointerRNA *ptr, const char *value)
{
AssetData *asset_data = ptr->data;
if (asset_data->description) {
MEM_freeN(asset_data->description);
}
if (value[0]) {
asset_data->description = BLI_strdup(value);
}
else {
asset_data->description = NULL;
}
}
#else
static void rna_def_custom_tag(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "CustomTag", NULL);
RNA_def_struct_ui_text(srna, "Custom Tag", "User defined tag (name token)");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_NAME);
RNA_def_property_ui_text(prop, "Name", "The identifier that makes up this tag");
RNA_def_struct_name_property(srna, prop);
}
static void rna_def_asset_custom_tags_api(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "CustomTags");
srna = RNA_def_struct(brna, "CustomTags", NULL);
RNA_def_struct_sdna(srna, "AssetData");
RNA_def_struct_ui_text(srna, "Asset Tags", "Collection of custom asset tags");
/* Tag collection */
func = RNA_def_function(srna, "new", "rna_AssetData_tag_new");
RNA_def_function_ui_description(func, "Add a new tag to this asset");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
/* return type */
parm = RNA_def_pointer(func, "tag", "CustomTag", "", "New tag");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_AssetData_tag_remove");
RNA_def_function_ui_description(func, "Remove an existing tag from this asset");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
/* tag to remove */
parm = RNA_def_pointer(func, "tag", "CustomTag", "", "Removed tag");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
}
static void rna_def_asset_data(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "AssetData", NULL);
RNA_def_struct_ui_text(srna, "Asset Data", "Additional data stored for an asset data-block");
// RNA_def_struct_ui_icon(srna, ICON_ASSET); /* TODO: Icon doesn't exist!. */
/* The struct has custom properties, but no pointer properties to other IDs! */
RNA_def_struct_idprops_func(srna, "rna_AssetData_idprops");
RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES); /* Mandatory! */
prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_AssetData_description_get",
"rna_AssetData_description_length",
"rna_AssetData_description_set");
RNA_def_property_ui_text(
prop, "Description", "A description of the asset to be displayed for the user");
prop = RNA_def_property(srna, "author", PROP_STRING, PROP_NONE);
RNA_def_property_string_maxlength(prop, MAX_NAME);
RNA_def_property_ui_text(prop, "Author", "Name of the person responsible for the asset");
prop = RNA_def_property(srna, "tags", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "CustomTag");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop,
"Tags",
"Custom tags (name tokens) for the asset, used for filtering and "
"general asset management");
rna_def_asset_custom_tags_api(brna, prop);
}
void RNA_def_asset(BlenderRNA *brna)
{
RNA_define_animate_sdna(false);
rna_def_custom_tag(brna);
rna_def_asset_data(brna);
RNA_define_animate_sdna(true);
}
#endif

View File

@@ -152,6 +152,7 @@ void RNA_def_animation(struct BlenderRNA *brna);
void RNA_def_animviz(struct BlenderRNA *brna);
void RNA_def_armature(struct BlenderRNA *brna);
void RNA_def_attribute(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

@@ -5907,6 +5907,11 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_BLENDER, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_asset_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_ASSETS_ONLY);
RNA_def_property_ui_text(prop, "Only Assets", "Hide .blend files items that are not assets");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "filter_id", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "FileSelectIDFilter");

View File

@@ -198,6 +198,8 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
ot->srna, "filter_blenlib", (filter & FILE_TYPE_BLENDERLIB) != 0, "Filter Blender IDs", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
/* TODO asset only filter? */
prop = RNA_def_int(
ot->srna,
"filemode",

View File

@@ -277,7 +277,7 @@ void WM_operatortype_last_properties_clear_all(void)
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
if (ot->last_properties) {
IDP_FreeProperty(ot->last_properties);
IDP_FreeProperty_ex(ot->last_properties, false);
ot->last_properties = NULL;
}
}