Initial "All" asset library loading support
An "All" asset library can be selected in the Asset Browser and asset view templates now, and that will load all assets from all asset libraries. Preview loading, drag & drop and asset catalogs don't work yet.
This commit is contained in:
parent
67194fb247
commit
33bcc4f430
|
@ -120,6 +120,9 @@ Vector<AssetLibraryReference> all_valid_asset_library_refs();
|
|||
blender::asset_system::AssetLibrary *AS_asset_library_load(
|
||||
const Main *bmain, const AssetLibraryReference &library_reference);
|
||||
|
||||
std::string AS_asset_library_root_path_from_library_ref(
|
||||
const AssetLibraryReference &library_reference);
|
||||
|
||||
/**
|
||||
* Try to find an appropriate location for an asset library root from a file or directory path.
|
||||
* Does not check if \a input_path exists.
|
||||
|
|
|
@ -64,6 +64,12 @@ bool AS_asset_library_has_any_unsaved_catalogs()
|
|||
return service->has_any_unsaved_catalogs();
|
||||
}
|
||||
|
||||
std::string AS_asset_library_root_path_from_library_ref(
|
||||
const AssetLibraryReference &library_reference)
|
||||
{
|
||||
return AssetLibraryService::root_path_from_library_ref(library_reference);
|
||||
}
|
||||
|
||||
std::string AS_asset_library_find_suitable_root_path_from_path(
|
||||
const blender::StringRefNull input_path)
|
||||
{
|
||||
|
@ -224,6 +230,7 @@ void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data)
|
|||
STRNCPY(asset_data->catalog_simple_name, catalog->simple_name.c_str());
|
||||
}
|
||||
|
||||
/* TODO get rid of this. */
|
||||
Vector<AssetLibraryReference> all_valid_asset_library_refs()
|
||||
{
|
||||
Vector<AssetLibraryReference> result;
|
||||
|
|
|
@ -68,12 +68,17 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||
|
||||
return get_asset_library_on_disk(root_path);
|
||||
}
|
||||
if (library_reference.type == ASSET_LIBRARY_CUSTOM) {
|
||||
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
|
||||
&U, library_reference.custom_library_index);
|
||||
|
||||
if (user_library) {
|
||||
return get_asset_library_on_disk(user_library->path);
|
||||
/* TODO */
|
||||
if (library_reference.type == ASSET_LIBRARY_ALL) {
|
||||
return get_asset_library_current_file();
|
||||
}
|
||||
|
||||
if (library_reference.type == ASSET_LIBRARY_CUSTOM) {
|
||||
std::string root_path = root_path_from_library_ref(library_reference);
|
||||
|
||||
if (!root_path.empty()) {
|
||||
return get_asset_library_on_disk(root_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +138,31 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file()
|
|||
return lib;
|
||||
}
|
||||
|
||||
std::string AssetLibraryService::root_path_from_library_ref(
|
||||
const AssetLibraryReference &library_reference)
|
||||
{
|
||||
if (ELEM(library_reference.type, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const char *top_level_directory = nullptr;
|
||||
|
||||
BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM);
|
||||
BLI_assert(library_reference.custom_library_index >= 0);
|
||||
|
||||
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
|
||||
&U, library_reference.custom_library_index);
|
||||
if (user_library) {
|
||||
top_level_directory = user_library->path;
|
||||
}
|
||||
|
||||
if (!top_level_directory) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return normalize_directory_path(top_level_directory);
|
||||
}
|
||||
|
||||
void AssetLibraryService::allocate_service_instance()
|
||||
{
|
||||
instance_ = std::make_unique<AssetLibraryService>();
|
||||
|
|
|
@ -54,6 +54,8 @@ class AssetLibraryService {
|
|||
/** Destroy the AssetLibraryService singleton. It will be reallocated by #get() if necessary. */
|
||||
static void destroy();
|
||||
|
||||
static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference);
|
||||
|
||||
AssetLibrary *get_asset_library(const Main *bmain,
|
||||
const AssetLibraryReference &library_reference);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ class AssetStorage {
|
|||
* faster lookups. Not possible until each asset is only represented once in the storage. */
|
||||
StorageT local_id_assets_;
|
||||
|
||||
friend class AssetLibrary;
|
||||
|
||||
public:
|
||||
/** See #AssetLibrary::add_external_asset(). */
|
||||
AssetRepresentation &add_external_asset(StringRef name, std::unique_ptr<AssetMetaData> metadata);
|
||||
|
|
|
@ -47,7 +47,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
|
|||
if (value < ASSET_LIBRARY_CUSTOM) {
|
||||
library.type = value;
|
||||
library.custom_library_index = -1;
|
||||
BLI_assert(ELEM(value, ASSET_LIBRARY_LOCAL));
|
||||
BLI_assert(ELEM(value, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL));
|
||||
return library;
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,11 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(
|
|||
|
||||
if (include_local_library) {
|
||||
const EnumPropertyItem predefined_items[] = {
|
||||
/* For the future. */
|
||||
// {ASSET_REPO_BUNDLED, "BUNDLED", 0, "Bundled", "Show the default user assets"},
|
||||
{ASSET_LIBRARY_ALL,
|
||||
"ALL",
|
||||
ICON_NONE,
|
||||
"All",
|
||||
"Show assets from all of the listed asset libraries"},
|
||||
{ASSET_LIBRARY_LOCAL,
|
||||
"LOCAL",
|
||||
ICON_CURRENT_FILE,
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "AS_asset_library.hh"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
|
@ -130,16 +132,7 @@ AssetList::AssetList(eFileSelectType filesel_type, const AssetLibraryReference &
|
|||
void AssetList::setup()
|
||||
{
|
||||
FileList *files = filelist_;
|
||||
|
||||
bUserAssetLibrary *user_library = nullptr;
|
||||
|
||||
/* Ensure valid repository, or fall-back to local one. */
|
||||
if (library_ref_.type == ASSET_LIBRARY_CUSTOM) {
|
||||
BLI_assert(library_ref_.custom_library_index >= 0);
|
||||
|
||||
user_library = BKE_preferences_asset_library_find_from_index(
|
||||
&U, library_ref_.custom_library_index);
|
||||
}
|
||||
std::string asset_lib_path = AS_asset_library_root_path_from_library_ref(library_ref_);
|
||||
|
||||
/* Relevant bits from file_refresh(). */
|
||||
/* TODO pass options properly. */
|
||||
|
@ -161,13 +154,10 @@ void AssetList::setup()
|
|||
filelist_setindexer(files, use_asset_indexer ? &file_indexer_asset : &file_indexer_noop);
|
||||
|
||||
char path[FILE_MAXDIR] = "";
|
||||
if (user_library) {
|
||||
BLI_strncpy(path, user_library->path, sizeof(path));
|
||||
filelist_setdir(files, path);
|
||||
}
|
||||
else {
|
||||
filelist_setdir(files, path);
|
||||
if (!asset_lib_path.empty()) {
|
||||
BLI_strncpy(path, asset_lib_path.c_str(), sizeof(path));
|
||||
}
|
||||
filelist_setdir(files, path);
|
||||
}
|
||||
|
||||
void AssetList::fetch(const bContext &C)
|
||||
|
@ -376,7 +366,9 @@ void AssetListStorage::remapID(ID *id_new, ID *id_old)
|
|||
std::optional<eFileSelectType> AssetListStorage::asset_library_reference_to_fileselect_type(
|
||||
const AssetLibraryReference &library_reference)
|
||||
{
|
||||
switch (library_reference.type) {
|
||||
switch (eAssetLibraryType(library_reference.type)) {
|
||||
case ASSET_LIBRARY_ALL:
|
||||
return FILE_ASSET_LIBRARY_ALL;
|
||||
case ASSET_LIBRARY_CUSTOM:
|
||||
return FILE_ASSET_LIBRARY;
|
||||
case ASSET_LIBRARY_LOCAL:
|
||||
|
|
|
@ -555,6 +555,7 @@ static void file_draw_preview(const SpaceFile *sfile,
|
|||
/* path is no more static, cannot give it directly to but... */
|
||||
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
|
||||
(file->typeflag & FILE_TYPE_ASSET) != 0) {
|
||||
/* TODO enable drag & drop support, get path from asset representation. */
|
||||
char blend_path[FILE_MAX_LIBEXTRA];
|
||||
|
||||
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
|
||||
|
|
|
@ -320,6 +320,10 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
|
|||
bool *stop,
|
||||
bool *do_update,
|
||||
float *progress);
|
||||
static void filelist_readjob_all_asset_libraries(FileListReadJob *job_params,
|
||||
bool *stop,
|
||||
bool *do_update,
|
||||
float *progress);
|
||||
|
||||
/* helper, could probably go in BKE actually? */
|
||||
static int groupname_to_code(const char *group);
|
||||
|
@ -854,13 +858,16 @@ static bool is_filtered_lib_type(FileListInternEntry *file,
|
|||
const char *root,
|
||||
FileListFilter *filter)
|
||||
{
|
||||
char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name;
|
||||
if (root) {
|
||||
char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name;
|
||||
|
||||
BLI_path_join(path, sizeof(path), root, file->relpath);
|
||||
BLI_path_join(path, sizeof(path), root, file->relpath);
|
||||
|
||||
if (BLO_library_path_explode(path, dir, &group, &name)) {
|
||||
return is_filtered_id_file_type(file, group, name, filter);
|
||||
if (BLO_library_path_explode(path, dir, &group, &name)) {
|
||||
return is_filtered_id_file_type(file, group, name, filter);
|
||||
}
|
||||
}
|
||||
|
||||
return is_filtered_file_type(file, filter);
|
||||
}
|
||||
|
||||
|
@ -1359,11 +1366,10 @@ static bool filelist_checkdir_main(struct FileList *filelist, char *r_dir, const
|
|||
return filelist_checkdir_lib(filelist, r_dir, do_change);
|
||||
}
|
||||
|
||||
static bool filelist_checkdir_main_assets(struct FileList * /*filelist*/,
|
||||
char * /*r_dir*/,
|
||||
const bool /*do_change*/)
|
||||
static bool filelist_checkdir_return_always_valid(struct FileList * /*filelist*/,
|
||||
char * /*r_dir*/,
|
||||
const bool /*do_change*/)
|
||||
{
|
||||
/* Main is always valid. */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1625,6 +1631,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
|
|||
BLI_thread_queue_push(cache->previews_done, preview);
|
||||
}
|
||||
else {
|
||||
/* XXX */
|
||||
if (entry->redirection_path) {
|
||||
BLI_strncpy(preview->filepath, entry->redirection_path, FILE_MAXDIR);
|
||||
}
|
||||
|
@ -1766,12 +1773,19 @@ void filelist_settype(FileList *filelist, short type)
|
|||
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA;
|
||||
break;
|
||||
case FILE_MAIN_ASSET:
|
||||
filelist->check_dir_fn = filelist_checkdir_main_assets;
|
||||
filelist->check_dir_fn = filelist_checkdir_return_always_valid;
|
||||
filelist->read_job_fn = filelist_readjob_main_assets;
|
||||
filelist->prepare_filter_fn = prepare_filter_asset_library;
|
||||
filelist->filter_fn = is_filtered_main_assets;
|
||||
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA | FILELIST_TAGS_NO_THREADS;
|
||||
break;
|
||||
case FILE_ASSET_LIBRARY_ALL:
|
||||
filelist->check_dir_fn = filelist_checkdir_return_always_valid;
|
||||
filelist->read_job_fn = filelist_readjob_all_asset_libraries;
|
||||
filelist->prepare_filter_fn = prepare_filter_asset_library;
|
||||
filelist->filter_fn = is_filtered_asset_library;
|
||||
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA;
|
||||
break;
|
||||
default:
|
||||
filelist->check_dir_fn = filelist_checkdir_dir;
|
||||
filelist->read_job_fn = filelist_readjob_dir;
|
||||
|
@ -2852,6 +2866,9 @@ void filelist_entry_parent_select_set(FileList *filelist,
|
|||
|
||||
bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group)
|
||||
{
|
||||
if (filelist->asset_library) {
|
||||
return true;
|
||||
}
|
||||
return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr);
|
||||
}
|
||||
|
||||
|
@ -3746,6 +3763,10 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
|
|||
*/
|
||||
static bool filelist_contains_main(const FileList *filelist, const Main *bmain)
|
||||
{
|
||||
if (filelist->asset_library_ref && (filelist->asset_library_ref->type == ASSET_LIBRARY_ALL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *blendfile_path = BKE_main_blendfile_path(bmain);
|
||||
return blendfile_path[0] && BLI_path_contains(filelist->filelist.root, blendfile_path);
|
||||
}
|
||||
|
@ -3800,6 +3821,40 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
|
|||
filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress);
|
||||
}
|
||||
|
||||
static void filelist_readjob_all_asset_libraries(FileListReadJob *job_params,
|
||||
bool *stop,
|
||||
bool *do_update,
|
||||
float *progress)
|
||||
{
|
||||
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
|
||||
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
|
||||
(filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
|
||||
|
||||
filelist_readjob_load_asset_library_data(job_params, do_update);
|
||||
|
||||
/* A valid, but empty file-list from now. */
|
||||
filelist->filelist.entries_num = 0;
|
||||
|
||||
filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress);
|
||||
|
||||
/* When only doing partialy reload for main data, we're done. */
|
||||
if (job_params->only_main_data) {
|
||||
return;
|
||||
}
|
||||
/* TODO propertly update progress? */
|
||||
|
||||
for (const AssetLibraryReference &library_ref : asset_system::all_valid_asset_library_refs()) {
|
||||
if (library_ref.type == ASSET_LIBRARY_LOCAL) {
|
||||
/* Already added main assets above. */
|
||||
continue;
|
||||
}
|
||||
std::string library_path = AS_asset_library_root_path_from_library_ref(library_ref);
|
||||
BLI_strncpy(filelist->filelist.root, library_path.c_str(), sizeof(filelist->filelist.root));
|
||||
|
||||
filelist_readjob_recursive_dir_add_items(true, job_params, stop, do_update, progress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the read-job is requesting a partial reread of the file list only.
|
||||
*/
|
||||
|
|
|
@ -423,16 +423,20 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
|
|||
}
|
||||
|
||||
switch (library->type) {
|
||||
case ASSET_LIBRARY_ALL:
|
||||
base_params->dir[0] = '\0';
|
||||
base_params->type = FILE_ASSET_LIBRARY_ALL;
|
||||
break;
|
||||
case ASSET_LIBRARY_LOCAL:
|
||||
base_params->dir[0] = '\0';
|
||||
base_params->type = FILE_MAIN_ASSET;
|
||||
break;
|
||||
case ASSET_LIBRARY_CUSTOM:
|
||||
BLI_assert(user_library);
|
||||
BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir));
|
||||
base_params->type = FILE_ASSET_LIBRARY;
|
||||
break;
|
||||
}
|
||||
base_params->type = (library->type == ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET :
|
||||
FILE_ASSET_LIBRARY;
|
||||
}
|
||||
|
||||
void fileselect_refresh_params(SpaceFile *sfile)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define _DNA_DEFAULT_AssetLibraryReference \
|
||||
{ \
|
||||
.type = ASSET_LIBRARY_LOCAL, \
|
||||
/* Not needed really (should be ignored for #ASSET_LIBRARY_LOCAL), but helps debugging. */ \
|
||||
/* Not needed really (should be ignored for anything but #ASSET_LIBRARY_CUSTOM), but helps debugging. */ \
|
||||
.custom_library_index = -1, \
|
||||
}
|
||||
|
||||
|
|
|
@ -88,8 +88,7 @@ typedef enum eAssetLibraryType {
|
|||
// ASSET_LIBRARY_BUNDLED = 0,
|
||||
/** Display assets from the current session (current "Main"). */
|
||||
ASSET_LIBRARY_LOCAL = 1,
|
||||
/* For the future. Display assets for the current project. */
|
||||
// ASSET_LIBRARY_PROJECT = 2,
|
||||
ASSET_LIBRARY_ALL = 2,
|
||||
|
||||
/** Display assets from custom asset libraries, as defined in the preferences
|
||||
* (#bUserAssetLibrary). The name will be taken from #FileSelectParams.asset_library_ref.idname
|
||||
|
|
|
@ -995,12 +995,15 @@ enum eFileDetails {
|
|||
|
||||
/** File selector types. */
|
||||
typedef enum eFileSelectType {
|
||||
FILE_SELECT_TYPE_UNSET = 0,
|
||||
FILE_LOADLIB = 1,
|
||||
FILE_MAIN = 2,
|
||||
/** Load assets from #Main. */
|
||||
FILE_MAIN_ASSET = 3,
|
||||
/** Load assets of an asset library containing external files. */
|
||||
FILE_ASSET_LIBRARY = 4,
|
||||
/** Load all asset libraries. */
|
||||
FILE_ASSET_LIBRARY_ALL = 5,
|
||||
|
||||
FILE_UNIX = 8,
|
||||
FILE_BLENDER = 8, /* don't display relative paths */
|
||||
|
|
Loading…
Reference in New Issue