From ae84a2956ec61bc182f23c7a914fca3f37a5c83f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 15 Feb 2023 12:47:47 +0100 Subject: [PATCH] Assets: Preference for default import method for an asset library The default import method for an asset library can now be determined in the Preferences. The Asset Browser has a new "Follow Preferences" option for the importing. The essentials asset library still only uses "Append (Reuse Data)". This is part of #104686, which aims at improving the import method selection, especially for the introduction of the new essentials library (which doesn't support certain import methods). Further changes are coming to improve the UI, see #104686. Pull Request: #104688 --- .../scripts/startup/bl_ui/space_userpref.py | 8 ++++ .../blender/asset_system/AS_asset_library.hh | 10 ++-- .../asset_system/AS_asset_representation.hh | 15 ++++++ .../intern/asset_library_service.cc | 48 +++++++++++++------ .../intern/asset_library_service.hh | 3 ++ .../intern/asset_representation.cc | 39 ++++++++++++--- .../blender/blenkernel/BKE_blender_version.h | 4 +- .../blender/blenkernel/intern/preferences.c | 3 ++ .../blenloader/intern/versioning_300.cc | 42 ++++++++++++---- .../blenloader/intern/versioning_userdef.c | 6 +++ .../blender/editors/asset/ED_asset_handle.h | 8 ++++ .../editors/asset/intern/asset_handle.cc | 6 +++ .../blender/editors/include/ED_fileselect.h | 16 +++++++ source/blender/editors/include/UI_interface.h | 2 +- .../interface_template_asset_view.cc | 5 +- source/blender/editors/space_file/file_draw.c | 29 ++++++----- source/blender/editors/space_file/filesel.cc | 42 +++++++++++++++- source/blender/makesdna/DNA_asset_types.h | 11 +++++ source/blender/makesdna/DNA_space_types.h | 2 + source/blender/makesdna/DNA_userdef_types.h | 3 ++ source/blender/makesrna/intern/rna_space.c | 6 +++ source/blender/makesrna/intern/rna_userdef.c | 25 ++++++++++ source/blender/windowmanager/WM_api.h | 2 +- source/blender/windowmanager/WM_types.h | 2 +- .../windowmanager/intern/wm_dragdrop.cc | 15 +++--- 25 files changed, 289 insertions(+), 63 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index fa5f451f9ee..a7dcd9f68b8 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1442,12 +1442,20 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel): row = name_col.row() row.alert = not library.name row.prop(library, "name", text="") + row = name_col.row() + # Dummy for spacing + row.label(text="") + name_col.separator() row = path_col.row() subrow = row.row() subrow.alert = not library.path subrow.prop(library, "path", text="") row.operator("preferences.asset_library_remove", text="", icon='X', emboss=False).index = i + row = path_col.row() + row.prop(library, "import_method", text="") + row.label(text="", icon='BLANK1') + path_col.separator() row = box.row() row.alignment = 'RIGHT' diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index d487f9711fd..290e8e44b9f 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -19,6 +19,7 @@ #include "BKE_callbacks.h" struct AssetLibrary; +class bUserAssetLibrary; struct IDRemapper; struct Main; @@ -58,6 +59,11 @@ class AssetLibrary { std::function on_refresh_; + std::optional import_method_; + /** Assets owned by this library may be imported with a different method than set in + * #import_method_ above, it's just a default. */ + bool may_override_import_method_ = false; + bCallbackFuncStore on_save_callback_store_{}; public: @@ -67,10 +73,8 @@ class AssetLibrary { std::unique_ptr catalog_service; - /** Assets owned by this library should never be linked. */ - bool never_link = false; - friend class AssetLibraryService; + friend class AssetRepresentation; public: /** diff --git a/source/blender/asset_system/AS_asset_representation.hh b/source/blender/asset_system/AS_asset_representation.hh index 6793cd8097c..99fde7d3dc2 100644 --- a/source/blender/asset_system/AS_asset_representation.hh +++ b/source/blender/asset_system/AS_asset_representation.hh @@ -12,10 +12,13 @@ #pragma once #include +#include #include #include "BLI_string_ref.hh" +#include "DNA_asset_types.h" + #include "AS_asset_identifier.hh" struct AssetMetaData; @@ -70,6 +73,15 @@ class AssetRepresentation { StringRefNull get_name() const; AssetMetaData &get_metadata() const; + /** Get the import method to use for this asset. A different one may be used if + * #may_override_import_method() returns true, otherwise, the returned value must be used. If + * there is no import method predefined for this asset no value is returned. + */ + std::optional get_import_method() const; + /** Returns if this asset may be imported with an import method other than the one returned by + * #get_import_method(). Also returns true if there is no predefined import method + * (when #get_import_method() returns no value). */ + bool may_override_import_method() const; /** Returns if this asset is stored inside this current file, and as such fully editable. */ bool is_local_id() const; const AssetLibrary &owner_asset_library() const; @@ -81,3 +93,6 @@ class AssetRepresentation { struct AssetRepresentation; const std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset); +std::optional AS_asset_representation_import_method_get( + const ::AssetRepresentation *asset_handle); +bool AS_asset_representation_may_override_import_method(const ::AssetRepresentation *asset_handle); diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index b9ae8e7bd69..cf52f9d1d76 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -63,9 +63,11 @@ AssetLibrary *AssetLibraryService::get_asset_library( switch (type) { case ASSET_LIBRARY_ESSENTIALS: { const StringRefNull root_path = essentials_directory_path(); - AssetLibrary *asset_library = get_asset_library_on_disk(root_path); - asset_library->never_link = true; - return asset_library; + + AssetLibrary *library = get_asset_library_on_disk(root_path); + library->import_method_ = ASSET_IMPORT_APPEND_REUSE; + + return library; } case ASSET_LIBRARY_LOCAL: { /* For the "Current File" library we get the asset library root path based on main. */ @@ -81,12 +83,22 @@ AssetLibrary *AssetLibraryService::get_asset_library( case ASSET_LIBRARY_ALL: return get_asset_library_all(bmain); case 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); + bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref( + library_reference); + if (!custom_library) { + return nullptr; } - break; + + std::string root_path = custom_library->path; + if (root_path.empty()) { + return nullptr; + } + + AssetLibrary *library = get_asset_library_on_disk(root_path); + library->import_method_ = eAssetImportMethod(custom_library->import_method); + library->may_override_import_method_ = true; + + return library; } } @@ -187,6 +199,15 @@ AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain) return all_library_.get(); } +bUserAssetLibrary *AssetLibraryService::find_custom_asset_library_from_library_ref( + const AssetLibraryReference &library_reference) +{ + BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM); + BLI_assert(library_reference.custom_library_index >= 0); + + return BKE_preferences_asset_library_find_from_index(&U, library_reference.custom_library_index); +} + std::string AssetLibraryService::root_path_from_library_ref( const AssetLibraryReference &library_reference) { @@ -194,16 +215,13 @@ std::string AssetLibraryService::root_path_from_library_ref( return ""; } - 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 || !user_library->path[0]) { + bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref( + library_reference); + if (!custom_library || !custom_library->path[0]) { return ""; } - return user_library->path; + return custom_library->path; } void AssetLibraryService::allocate_service_instance() diff --git a/source/blender/asset_system/intern/asset_library_service.hh b/source/blender/asset_system/intern/asset_library_service.hh index 1dd9bda7aca..1c0a2e9dc36 100644 --- a/source/blender/asset_system/intern/asset_library_service.hh +++ b/source/blender/asset_system/intern/asset_library_service.hh @@ -14,6 +14,7 @@ #include struct AssetLibraryReference; +struct bUserAssetLibrary; namespace blender::asset_system { @@ -58,6 +59,8 @@ class AssetLibraryService { static void destroy(); static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference); + static bUserAssetLibrary *find_custom_asset_library_from_library_ref( + const AssetLibraryReference &library_reference); AssetLibrary *get_asset_library(const Main *bmain, const AssetLibraryReference &library_reference); diff --git a/source/blender/asset_system/intern/asset_representation.cc b/source/blender/asset_system/intern/asset_representation.cc index 5d3660e4bb3..daaa7bdff0f 100644 --- a/source/blender/asset_system/intern/asset_representation.cc +++ b/source/blender/asset_system/intern/asset_representation.cc @@ -8,6 +8,7 @@ #include "DNA_ID.h" #include "DNA_asset_types.h" +#include "DNA_userdef_types.h" #include "AS_asset_identifier.hh" #include "AS_asset_library.hh" @@ -80,6 +81,22 @@ AssetMetaData &AssetRepresentation::get_metadata() const return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_; } +std::optional AssetRepresentation::get_import_method() const +{ + if (!owner_asset_library_) { + return {}; + } + return owner_asset_library_->import_method_; +} + +bool AssetRepresentation::may_override_import_method() const +{ + if (!owner_asset_library_ || !owner_asset_library_->import_method_) { + return true; + } + return owner_asset_library_->may_override_import_method_; +} + bool AssetRepresentation::is_local_id() const { return is_local_id_; @@ -102,6 +119,21 @@ const std::string AS_asset_representation_full_path_get(const AssetRepresentatio return identifier.full_path(); } +std::optional AS_asset_representation_import_method_get( + const AssetRepresentation *asset_handle) +{ + const asset_system::AssetRepresentation *asset = + reinterpret_cast(asset_handle); + return asset->get_import_method(); +} + +bool AS_asset_representation_may_override_import_method(const AssetRepresentation *asset_handle) +{ + const asset_system::AssetRepresentation *asset = + reinterpret_cast(asset_handle); + return asset->may_override_import_method(); +} + /* ---------------------------------------------------------------------- */ /** \name C-API * \{ */ @@ -127,11 +159,4 @@ bool AS_asset_representation_is_local_id(const AssetRepresentation *asset_handle return asset->is_local_id(); } -bool AS_asset_representation_is_never_link(const AssetRepresentation *asset_handle) -{ - const asset_system::AssetRepresentation *asset = - reinterpret_cast(asset_handle); - return asset->owner_asset_library().never_link; -} - /** \} */ diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 395a0c34538..e83abeae329 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -23,9 +23,11 @@ extern "C" { /** Blender release cycle stage: alpha/beta/rc/release. */ #define BLENDER_VERSION_CYCLE alpha +/* TODO proper version bump. */ + /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 9 +#define BLENDER_FILE_SUBVERSION 10 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/intern/preferences.c b/source/blender/blenkernel/intern/preferences.c index dd76f9eddc1..02169cd4535 100644 --- a/source/blender/blenkernel/intern/preferences.c +++ b/source/blender/blenkernel/intern/preferences.c @@ -8,6 +8,8 @@ #include +#include "DNA_asset_types.h" + #include "MEM_guardedalloc.h" #include "BLI_fileops.h" @@ -44,6 +46,7 @@ bUserAssetLibrary *BKE_preferences_asset_library_add(UserDef *userdef, if (path) { BLI_strncpy(library->path, path, sizeof(library->path)); } + library->import_method = ASSET_IMPORT_APPEND_REUSE; return library; } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index ca39543c841..4a1c14bd430 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3913,16 +3913,27 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - "versioning_userdef.c", #blo_do_versions_userdef - * - "versioning_userdef.c", #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { + if (!MAIN_VERSION_ATLEAST(bmain, 305, 10)) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype != SPACE_FILE) { + continue; + } + SpaceFile *sfile = reinterpret_cast(sl); + if (!sfile->asset_params) { + continue; + } + + /* When an asset browser uses the default import method, make it follow the new + * preference setting. This means no effective default behavior change. */ + if (sfile->asset_params->import_type == FILE_ASSET_IMPORT_APPEND_REUSE) { + sfile->asset_params->import_type = FILE_ASSET_IMPORT_FOLLOW_PREFS; + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "int", "shadow_pool_size")) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { scene->eevee.flag |= SCE_EEVEE_SHADOW_ENABLED; @@ -3960,7 +3971,18 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } } + } + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #blo_do_versions_userdef + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { /* Keep this block, even when empty. */ } } diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 10a21356c8f..3c4b1a04d63 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -773,6 +773,12 @@ void blo_do_versions_userdef(UserDef *userdef) userdef->gpu_backend = GPU_BACKEND_OPENGL; } + if (!USER_VERSION_ATLEAST(305, 10)) { + LISTBASE_FOREACH (bUserAssetLibrary *, asset_library, &userdef->asset_libraries) { + asset_library->import_method = ASSET_IMPORT_APPEND_REUSE; + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/editors/asset/ED_asset_handle.h b/source/blender/editors/asset/ED_asset_handle.h index b3d9b58b30e..436194fd885 100644 --- a/source/blender/editors/asset/ED_asset_handle.h +++ b/source/blender/editors/asset/ED_asset_handle.h @@ -13,6 +13,7 @@ #pragma once #include "DNA_ID_enums.h" +#include "DNA_asset_types.h" #ifdef __cplusplus extern "C" { @@ -37,6 +38,13 @@ void ED_asset_handle_get_full_library_path( #ifdef __cplusplus +# include + +/** The asset library may have an import method (e.g. append vs. link) defined to use. If so, this + * returns it. Otherwise a reasonable method should be used, usually "Append (Reuse Data)". */ +std::optional ED_asset_handle_get_import_method( + const struct AssetHandle *asset); + namespace blender::ed::asset { /** If the ID already exists in the database, return it, otherwise add it. */ diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc index 26b6f09b231..4a6a7fda40b 100644 --- a/source/blender/editors/asset/intern/asset_handle.cc +++ b/source/blender/editors/asset/intern/asset_handle.cc @@ -42,6 +42,12 @@ int ED_asset_handle_get_preview_icon_id(const AssetHandle *asset) return asset->file_data->preview_icon_id; } +std::optional ED_asset_handle_get_import_method( + const AssetHandle *asset_handle) +{ + return AS_asset_representation_import_method_get(asset_handle->file_data->asset); +} + void ED_asset_handle_get_full_library_path(const AssetHandle *asset_handle, char r_full_lib_path[FILE_MAX_LIBEXTRA]) { diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index cf9b423dd7a..df6fe03bf05 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -150,6 +150,22 @@ struct ID *ED_fileselect_active_asset_get(const struct SpaceFile *sfile); void ED_fileselect_activate_asset_catalog(const struct SpaceFile *sfile, bUUID catalog_id); +/** + * Resolve this space's #eFileAssetImportMethod to the #eAssetImportMethod (note the different + * type) to be used for the actual import of a specific asset. + * - If the asset system dictates a certain import method, this will be returned. + * - If the Asset Browser is set to follow the Preferences (#FILE_ASSET_IMPORT_FOLLOW_PREFS), the + * asset system determines the import method (which is the default from the Preferences). -1 is + * returned if the asset system doesn't specify a method (e.g. because the asset library doesn't + * come from the Preferences). + * - Otherwise, the Asset Browser determines (possibly overrides) the import method. + * + * \return -1 on error, for example when #FILE_ASSET_IMPORT_FOLLOW_PREFS was requested but the + * active asset library reference couldn't be found in the preferences. + */ +int /* #eAssetImportMethod */ ED_fileselect_asset_import_method_get( + const struct SpaceFile *sfile, const struct FileDirEntry *file); + /** * Activate and select the file that corresponds to the given ID. * Pass deferred=true to wait for the next refresh before activating. diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b04a276feb4..066aef1886d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1797,7 +1797,7 @@ void UI_but_drag_attach_image(uiBut *but, struct ImBuf *imb, float scale); void UI_but_drag_set_asset(uiBut *but, const struct AssetHandle *asset, const char *path, - int import_type, /* eFileAssetImportType */ + int import_type, /* eAssetImportType */ int icon, struct ImBuf *imb, float scale); diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc index 3e707031dd2..55b2e780a9e 100644 --- a/source/blender/editors/interface/interface_template_asset_view.cc +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -49,12 +49,15 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle) * away before too long. */ ED_asset_handle_get_full_library_path(asset_handle, blend_path); + const eAssetImportMethod import_method = + ED_asset_handle_get_import_method(asset_handle).value_or(ASSET_IMPORT_APPEND_REUSE); + if (blend_path[0]) { ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle); UI_but_drag_set_asset(but, asset_handle, BLI_strdup(blend_path), - FILE_ASSET_IMPORT_APPEND, + import_method, ED_asset_handle_get_preview_icon_id(asset_handle), imbuf, 1.0f); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index a940be844e0..97e6531eadd 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -128,19 +128,6 @@ static void draw_tile_background(const rcti *draw_rect, int colorid, int shade) UI_draw_roundbox_aa(&draw_rect_fl, true, 5.0f, color); } -static eFileAssetImportType get_asset_import_type(const SpaceFile *sfile, const FileDirEntry *file) -{ - const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); - BLI_assert(asset_params != NULL); - if (asset_params->import_type != FILE_ASSET_IMPORT_LINK) { - return asset_params->import_type; - } - if (AS_asset_representation_is_never_link(file->asset)) { - return FILE_ASSET_IMPORT_APPEND_REUSE; - } - return FILE_ASSET_IMPORT_LINK; -} - static void file_draw_icon(const SpaceFile *sfile, uiBlock *block, const FileDirEntry *file, @@ -180,10 +167,16 @@ static void file_draw_icon(const SpaceFile *sfile, ImBuf *preview_image = filelist_file_getimage(file); char blend_path[FILE_MAX_LIBEXTRA]; if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + BLI_assert(asset_params != NULL); + + const int import_method = ED_fileselect_asset_import_method_get(sfile, file); + BLI_assert(import_method > -1); + UI_but_drag_set_asset(but, &(AssetHandle){.file_data = file}, BLI_strdup(blend_path), - get_asset_import_type(sfile, file), + import_method, icon, preview_image, UI_DPI_FAC); @@ -570,10 +563,16 @@ static void file_draw_preview(const SpaceFile *sfile, char blend_path[FILE_MAX_LIBEXTRA]; if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + BLI_assert(asset_params != NULL); + + const int import_method = ED_fileselect_asset_import_method_get(sfile, file); + BLI_assert(import_method > -1); + UI_but_drag_set_asset(but, &(AssetHandle){.file_data = file}, BLI_strdup(blend_path), - get_asset_import_type(sfile, file), + import_method, icon, imb, scale); diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 4d6c94e6bae..45bbb25a4de 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -23,6 +23,8 @@ # include #endif +#include "AS_asset_representation.hh" + #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" @@ -58,6 +60,7 @@ #include "UI_interface_icons.h" #include "UI_view2d.h" +#include "AS_asset_representation.h" #include "AS_essentials_library.hh" #include "file_intern.h" @@ -106,7 +109,7 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) asset_params->base_params.details_flags = U_default.file_space_data.details_flags; asset_params->asset_library_ref.type = ASSET_LIBRARY_ALL; asset_params->asset_library_ref.custom_library_index = -1; - asset_params->import_type = FILE_ASSET_IMPORT_APPEND_REUSE; + asset_params->import_type = FILE_ASSET_IMPORT_FOLLOW_PREFS; } FileSelectParams *base_params = &asset_params->base_params; @@ -503,6 +506,43 @@ void ED_fileselect_activate_asset_catalog(const SpaceFile *sfile, const bUUID ca WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr); } +int ED_fileselect_asset_import_method_get(const SpaceFile *sfile, const FileDirEntry *file) +{ + if (!ED_fileselect_is_asset_browser(sfile) || !file->asset) { + return -1; + } + + /* First handle the case where the asset system dictates a certain import method. */ + if (AS_asset_representation_may_override_import_method(file->asset) == false) { + BLI_assert(AS_asset_representation_import_method_get(file->asset).has_value()); + + return *AS_asset_representation_import_method_get(file->asset); + } + + const FileAssetSelectParams *params = ED_fileselect_get_asset_params(sfile); + + if (params->import_type == FILE_ASSET_IMPORT_FOLLOW_PREFS) { + std::optional import_method = AS_asset_representation_import_method_get(file->asset); + return import_method ? *import_method : -1; + } + + switch (eFileAssetImportType(params->import_type)) { + case FILE_ASSET_IMPORT_LINK: + return ASSET_IMPORT_LINK; + case FILE_ASSET_IMPORT_APPEND: + return ASSET_IMPORT_APPEND; + case FILE_ASSET_IMPORT_APPEND_REUSE: + return ASSET_IMPORT_APPEND_REUSE; + + /* Should be handled above already. Break and fail below. */ + case FILE_ASSET_IMPORT_FOLLOW_PREFS: + break; + } + + BLI_assert_unreachable(); + return -1; +} + static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data) { ID *asset_id = (ID *)custom_data; diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h index d61e75d98c0..5ab24b2db4a 100644 --- a/source/blender/makesdna/DNA_asset_types.h +++ b/source/blender/makesdna/DNA_asset_types.h @@ -99,6 +99,17 @@ typedef enum eAssetLibraryType { ASSET_LIBRARY_CUSTOM = 100, } eAssetLibraryType; +typedef enum eAssetImportMethod { + /** Regular data-block linking. */ + ASSET_IMPORT_LINK = 0, + /** Regular data-block appending (basically linking + "Make Local"). */ + ASSET_IMPORT_APPEND = 1, + /** Append data-block with the #BLO_LIBLINK_APPEND_LOCAL_ID_REUSE flag enabled. Some typically + * heavy data dependencies (e.g. the image data-blocks of a material, the mesh of an object) may + * be reused from an earlier append. */ + ASSET_IMPORT_APPEND_REUSE = 2, +} eAssetImportMethod; + /** * Information to identify an asset library. May be either one of the predefined types (current * 'Main', builtin library, project library), or a custom type as defined in the Preferences. diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2742f62357d..2330d7dec7b 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -850,6 +850,8 @@ typedef enum eFileAssetImportType { * heavy data dependencies (e.g. the image data-blocks of a material, the mesh of an object) may * be reused from an earlier append. */ FILE_ASSET_IMPORT_APPEND_REUSE = 2, + /** Default: Follow the preference setting for this asset library. */ + FILE_ASSET_IMPORT_FOLLOW_PREFS = 3, } eFileAssetImportType; /** diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index bdf2210deae..91e950b540e 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -577,6 +577,9 @@ typedef struct bUserAssetLibrary { char name[64]; /* MAX_NAME */ char path[1024]; /* FILE_MAX */ + + short import_method; /* eAssetImportMethod */ + char _pad0[6]; } bUserAssetLibrary; typedef struct SolidLight { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 260e4c5bc7e..e8ee2593dc7 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -6912,6 +6912,12 @@ static void rna_def_fileselect_asset_params(BlenderRNA *brna) PropertyRNA *prop; static const EnumPropertyItem asset_import_type_items[] = { + {FILE_ASSET_IMPORT_FOLLOW_PREFS, + "FOLLOW_PREFS", + 0, + "Follow Preferences", + "Use the import method set in the Preferences for this asset library, don't override it " + "for this Asset Browser"}, {FILE_ASSET_IMPORT_LINK, "LINK", 0, "Link", "Import the assets as linked data-block"}, {FILE_ASSET_IMPORT_APPEND, "APPEND", diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 1b10a924b12..6fa8884c54c 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6134,6 +6134,31 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna) prop, "Path", "Path to a directory with .blend files to use as an asset library"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_userdef_asset_library_path_set"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + static const EnumPropertyItem import_method_items[] = { + {ASSET_IMPORT_LINK, "LINK", 0, "Link", "Import the assets as linked data-block"}, + {ASSET_IMPORT_APPEND, + "APPEND", + 0, + "Append", + "Import the assets as copied data-block, with no link to the original asset data-block"}, + {ASSET_IMPORT_APPEND_REUSE, + "APPEND_REUSE", + 0, + "Append (Reuse Data)", + "Import the assets as copied data-block while avoiding multiple copies of nested, " + "typically heavy data. For example the textures of a material asset, or the mesh of an " + "object asset, don't have to be copied every time this asset is imported. The instances of " + "the asset share the data instead"}, + {0, NULL, 0, NULL, NULL}, + }; + prop = RNA_def_property(srna, "import_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, import_method_items); + RNA_def_property_ui_text( + prop, + "Default Import Method", + "Determine how the asset will be imported, unless overridden by the Asset Browser"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_filepaths(BlenderRNA *brna) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 80785954a4e..d66cf407b55 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -1345,7 +1345,7 @@ bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode); */ wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset, const char *path, - int import_type); + int /* #eAssetImportMethod */ import_type); struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode); struct AssetMetaData *WM_drag_get_asset_meta_data(const struct wmDrag *drag, int idcode); /** diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 4c912f379dc..bdde49a1495 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -1074,7 +1074,7 @@ typedef struct wmDragAsset { const char *path; int id_type; struct AssetMetaData *metadata; - int import_type; /* eFileAssetImportType */ + int import_method; /* eAssetImportType */ /* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the * #wmDropBox. diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index 7b0056cc987..df621d25330 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -9,6 +9,7 @@ #include +#include "DNA_asset_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_windowmanager_types.h" @@ -563,7 +564,7 @@ wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *pat asset_drag->metadata = ED_asset_handle_get_metadata(asset); asset_drag->path = path; asset_drag->id_type = ED_asset_handle_get_id_type(asset); - asset_drag->import_type = import_type; + asset_drag->import_method = import_type; return asset_drag; } @@ -617,11 +618,11 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra) ViewLayer *view_layer = CTX_data_view_layer(asset_drag->evil_C); View3D *view3d = CTX_wm_view3d(asset_drag->evil_C); - switch ((eFileAssetImportType)asset_drag->import_type) { - case FILE_ASSET_IMPORT_LINK: + switch (eAssetImportMethod(asset_drag->import_method)) { + case ASSET_IMPORT_LINK: return WM_file_link_datablock( bmain, scene, view_layer, view3d, asset_drag->path, idtype, name, flag); - case FILE_ASSET_IMPORT_APPEND: + case ASSET_IMPORT_APPEND: return WM_file_append_datablock(bmain, scene, view_layer, @@ -631,7 +632,7 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra) name, flag | BLO_LIBLINK_APPEND_RECURSIVE | BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR); - case FILE_ASSET_IMPORT_APPEND_REUSE: + case ASSET_IMPORT_APPEND_REUSE: return WM_file_append_datablock(G_MAIN, scene, view_layer, @@ -655,7 +656,7 @@ bool WM_drag_asset_will_import_linked(const wmDrag *drag) } const wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0); - return asset_drag->import_type == FILE_ASSET_IMPORT_LINK; + return asset_drag->import_method == ASSET_IMPORT_LINK; } ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode) @@ -728,7 +729,7 @@ void WM_drag_add_asset_list_item(wmDrag *drag, const AssetHandle *asset) ED_asset_handle_get_full_library_path(asset, asset_blend_path); drag_asset->is_external = true; drag_asset->asset_data.external_info = WM_drag_create_asset_data( - asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND); + asset, BLI_strdup(asset_blend_path), ASSET_IMPORT_APPEND); } BLI_addtail(&drag->asset_items, drag_asset); }