forked from blender/blender
WIP: uv-simple-select #1
@ -1442,12 +1442,20 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel):
|
|||||||
row = name_col.row()
|
row = name_col.row()
|
||||||
row.alert = not library.name
|
row.alert = not library.name
|
||||||
row.prop(library, "name", text="")
|
row.prop(library, "name", text="")
|
||||||
|
row = name_col.row()
|
||||||
|
# Dummy for spacing
|
||||||
|
row.label(text="")
|
||||||
|
name_col.separator()
|
||||||
|
|
||||||
row = path_col.row()
|
row = path_col.row()
|
||||||
subrow = row.row()
|
subrow = row.row()
|
||||||
subrow.alert = not library.path
|
subrow.alert = not library.path
|
||||||
subrow.prop(library, "path", text="")
|
subrow.prop(library, "path", text="")
|
||||||
row.operator("preferences.asset_library_remove", text="", icon='X', emboss=False).index = i
|
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 = box.row()
|
||||||
row.alignment = 'RIGHT'
|
row.alignment = 'RIGHT'
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "BKE_callbacks.h"
|
#include "BKE_callbacks.h"
|
||||||
|
|
||||||
struct AssetLibrary;
|
struct AssetLibrary;
|
||||||
|
class bUserAssetLibrary;
|
||||||
struct IDRemapper;
|
struct IDRemapper;
|
||||||
struct Main;
|
struct Main;
|
||||||
|
|
||||||
@ -58,6 +59,11 @@ class AssetLibrary {
|
|||||||
|
|
||||||
std::function<void(AssetLibrary &self)> on_refresh_;
|
std::function<void(AssetLibrary &self)> on_refresh_;
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> 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_{};
|
bCallbackFuncStore on_save_callback_store_{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -67,10 +73,8 @@ class AssetLibrary {
|
|||||||
|
|
||||||
std::unique_ptr<AssetCatalogService> catalog_service;
|
std::unique_ptr<AssetCatalogService> catalog_service;
|
||||||
|
|
||||||
/** Assets owned by this library should never be linked. */
|
|
||||||
bool never_link = false;
|
|
||||||
|
|
||||||
friend class AssetLibraryService;
|
friend class AssetLibraryService;
|
||||||
|
friend class AssetRepresentation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -12,10 +12,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "BLI_string_ref.hh"
|
#include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
#include "AS_asset_identifier.hh"
|
#include "AS_asset_identifier.hh"
|
||||||
|
|
||||||
struct AssetMetaData;
|
struct AssetMetaData;
|
||||||
@ -70,6 +73,15 @@ class AssetRepresentation {
|
|||||||
|
|
||||||
StringRefNull get_name() const;
|
StringRefNull get_name() const;
|
||||||
AssetMetaData &get_metadata() 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<eAssetImportMethod> 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. */
|
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
||||||
bool is_local_id() const;
|
bool is_local_id() const;
|
||||||
const AssetLibrary &owner_asset_library() const;
|
const AssetLibrary &owner_asset_library() const;
|
||||||
@ -81,3 +93,6 @@ class AssetRepresentation {
|
|||||||
struct AssetRepresentation;
|
struct AssetRepresentation;
|
||||||
|
|
||||||
const std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
|
const std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
|
||||||
|
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
|
||||||
|
const ::AssetRepresentation *asset_handle);
|
||||||
|
bool AS_asset_representation_may_override_import_method(const ::AssetRepresentation *asset_handle);
|
||||||
|
@ -63,9 +63,11 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case ASSET_LIBRARY_ESSENTIALS: {
|
case ASSET_LIBRARY_ESSENTIALS: {
|
||||||
const StringRefNull root_path = essentials_directory_path();
|
const StringRefNull root_path = essentials_directory_path();
|
||||||
AssetLibrary *asset_library = get_asset_library_on_disk(root_path);
|
|
||||||
asset_library->never_link = true;
|
AssetLibrary *library = get_asset_library_on_disk(root_path);
|
||||||
return asset_library;
|
library->import_method_ = ASSET_IMPORT_APPEND_REUSE;
|
||||||
|
|
||||||
|
return library;
|
||||||
}
|
}
|
||||||
case ASSET_LIBRARY_LOCAL: {
|
case ASSET_LIBRARY_LOCAL: {
|
||||||
/* For the "Current File" library we get the asset library root path based on main. */
|
/* 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:
|
case ASSET_LIBRARY_ALL:
|
||||||
return get_asset_library_all(bmain);
|
return get_asset_library_all(bmain);
|
||||||
case ASSET_LIBRARY_CUSTOM: {
|
case ASSET_LIBRARY_CUSTOM: {
|
||||||
std::string root_path = root_path_from_library_ref(library_reference);
|
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
|
||||||
|
library_reference);
|
||||||
if (!root_path.empty()) {
|
if (!custom_library) {
|
||||||
return get_asset_library_on_disk(root_path);
|
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();
|
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(
|
std::string AssetLibraryService::root_path_from_library_ref(
|
||||||
const AssetLibraryReference &library_reference)
|
const AssetLibraryReference &library_reference)
|
||||||
{
|
{
|
||||||
@ -194,16 +215,13 @@ std::string AssetLibraryService::root_path_from_library_ref(
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM);
|
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
|
||||||
BLI_assert(library_reference.custom_library_index >= 0);
|
library_reference);
|
||||||
|
if (!custom_library || !custom_library->path[0]) {
|
||||||
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
|
|
||||||
&U, library_reference.custom_library_index);
|
|
||||||
if (!user_library || !user_library->path[0]) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return user_library->path;
|
return custom_library->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetLibraryService::allocate_service_instance()
|
void AssetLibraryService::allocate_service_instance()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
struct AssetLibraryReference;
|
struct AssetLibraryReference;
|
||||||
|
struct bUserAssetLibrary;
|
||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ class AssetLibraryService {
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference);
|
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,
|
AssetLibrary *get_asset_library(const Main *bmain,
|
||||||
const AssetLibraryReference &library_reference);
|
const AssetLibraryReference &library_reference);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
#include "DNA_asset_types.h"
|
#include "DNA_asset_types.h"
|
||||||
|
#include "DNA_userdef_types.h"
|
||||||
|
|
||||||
#include "AS_asset_identifier.hh"
|
#include "AS_asset_identifier.hh"
|
||||||
#include "AS_asset_library.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_;
|
return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> 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
|
bool AssetRepresentation::is_local_id() const
|
||||||
{
|
{
|
||||||
return is_local_id_;
|
return is_local_id_;
|
||||||
@ -102,6 +119,21 @@ const std::string AS_asset_representation_full_path_get(const AssetRepresentatio
|
|||||||
return identifier.full_path();
|
return identifier.full_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
|
||||||
|
const AssetRepresentation *asset_handle)
|
||||||
|
{
|
||||||
|
const asset_system::AssetRepresentation *asset =
|
||||||
|
reinterpret_cast<const asset_system::AssetRepresentation *>(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<const asset_system::AssetRepresentation *>(asset_handle);
|
||||||
|
return asset->may_override_import_method();
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/** \name C-API
|
/** \name C-API
|
||||||
* \{ */
|
* \{ */
|
||||||
@ -127,11 +159,4 @@ bool AS_asset_representation_is_local_id(const AssetRepresentation *asset_handle
|
|||||||
return asset->is_local_id();
|
return asset->is_local_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AS_asset_representation_is_never_link(const AssetRepresentation *asset_handle)
|
|
||||||
{
|
|
||||||
const asset_system::AssetRepresentation *asset =
|
|
||||||
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
|
||||||
return asset->owner_asset_library().never_link;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
@ -23,9 +23,11 @@ extern "C" {
|
|||||||
/** Blender release cycle stage: alpha/beta/rc/release. */
|
/** Blender release cycle stage: alpha/beta/rc/release. */
|
||||||
#define BLENDER_VERSION_CYCLE alpha
|
#define BLENDER_VERSION_CYCLE alpha
|
||||||
|
|
||||||
|
/* TODO proper version bump. */
|
||||||
|
|
||||||
/* Blender file format version. */
|
/* Blender file format version. */
|
||||||
#define BLENDER_FILE_VERSION BLENDER_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
|
/* 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
|
* version. Older Blender versions will test this and show a warning if the file
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BLI_fileops.h"
|
#include "BLI_fileops.h"
|
||||||
@ -44,6 +46,7 @@ bUserAssetLibrary *BKE_preferences_asset_library_add(UserDef *userdef,
|
|||||||
if (path) {
|
if (path) {
|
||||||
BLI_strncpy(library->path, path, sizeof(library->path));
|
BLI_strncpy(library->path, path, sizeof(library->path));
|
||||||
}
|
}
|
||||||
|
library->import_method = ASSET_IMPORT_APPEND_REUSE;
|
||||||
|
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
|
@ -3913,16 +3913,27 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (!MAIN_VERSION_ATLEAST(bmain, 305, 10)) {
|
||||||
* Versioning code until next subversion bump goes here.
|
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||||
*
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||||
* \note Be sure to check when bumping the version:
|
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
if (sl->spacetype != SPACE_FILE) {
|
||||||
* - "versioning_userdef.c", #do_versions_theme
|
continue;
|
||||||
*
|
}
|
||||||
* \note Keep this message at the bottom of the function.
|
SpaceFile *sfile = reinterpret_cast<SpaceFile *>(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")) {
|
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "int", "shadow_pool_size")) {
|
||||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||||
scene->eevee.flag |= SCE_EEVEE_SHADOW_ENABLED;
|
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. */
|
/* Keep this block, even when empty. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -773,6 +773,12 @@ void blo_do_versions_userdef(UserDef *userdef)
|
|||||||
userdef->gpu_backend = GPU_BACKEND_OPENGL;
|
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.
|
* Versioning code until next subversion bump goes here.
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DNA_ID_enums.h"
|
#include "DNA_ID_enums.h"
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -37,6 +38,13 @@ void ED_asset_handle_get_full_library_path(
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
# include <optional>
|
||||||
|
|
||||||
|
/** 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<eAssetImportMethod> ED_asset_handle_get_import_method(
|
||||||
|
const struct AssetHandle *asset);
|
||||||
|
|
||||||
namespace blender::ed::asset {
|
namespace blender::ed::asset {
|
||||||
|
|
||||||
/** If the ID already exists in the database, return it, otherwise add it. */
|
/** If the ID already exists in the database, return it, otherwise add it. */
|
||||||
|
@ -42,6 +42,12 @@ int ED_asset_handle_get_preview_icon_id(const AssetHandle *asset)
|
|||||||
return asset->file_data->preview_icon_id;
|
return asset->file_data->preview_icon_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> 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,
|
void ED_asset_handle_get_full_library_path(const AssetHandle *asset_handle,
|
||||||
char r_full_lib_path[FILE_MAX_LIBEXTRA])
|
char r_full_lib_path[FILE_MAX_LIBEXTRA])
|
||||||
{
|
{
|
||||||
|
@ -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);
|
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.
|
* Activate and select the file that corresponds to the given ID.
|
||||||
* Pass deferred=true to wait for the next refresh before activating.
|
* Pass deferred=true to wait for the next refresh before activating.
|
||||||
|
@ -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,
|
void UI_but_drag_set_asset(uiBut *but,
|
||||||
const struct AssetHandle *asset,
|
const struct AssetHandle *asset,
|
||||||
const char *path,
|
const char *path,
|
||||||
int import_type, /* eFileAssetImportType */
|
int import_type, /* eAssetImportType */
|
||||||
int icon,
|
int icon,
|
||||||
struct ImBuf *imb,
|
struct ImBuf *imb,
|
||||||
float scale);
|
float scale);
|
||||||
|
@ -49,12 +49,15 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
|
|||||||
* away before too long. */
|
* away before too long. */
|
||||||
ED_asset_handle_get_full_library_path(asset_handle, blend_path);
|
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]) {
|
if (blend_path[0]) {
|
||||||
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
||||||
UI_but_drag_set_asset(but,
|
UI_but_drag_set_asset(but,
|
||||||
asset_handle,
|
asset_handle,
|
||||||
BLI_strdup(blend_path),
|
BLI_strdup(blend_path),
|
||||||
FILE_ASSET_IMPORT_APPEND,
|
import_method,
|
||||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||||
imbuf,
|
imbuf,
|
||||||
1.0f);
|
1.0f);
|
||||||
|
@ -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);
|
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,
|
static void file_draw_icon(const SpaceFile *sfile,
|
||||||
uiBlock *block,
|
uiBlock *block,
|
||||||
const FileDirEntry *file,
|
const FileDirEntry *file,
|
||||||
@ -180,10 +167,16 @@ static void file_draw_icon(const SpaceFile *sfile,
|
|||||||
ImBuf *preview_image = filelist_file_getimage(file);
|
ImBuf *preview_image = filelist_file_getimage(file);
|
||||||
char blend_path[FILE_MAX_LIBEXTRA];
|
char blend_path[FILE_MAX_LIBEXTRA];
|
||||||
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
|
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,
|
UI_but_drag_set_asset(but,
|
||||||
&(AssetHandle){.file_data = file},
|
&(AssetHandle){.file_data = file},
|
||||||
BLI_strdup(blend_path),
|
BLI_strdup(blend_path),
|
||||||
get_asset_import_type(sfile, file),
|
import_method,
|
||||||
icon,
|
icon,
|
||||||
preview_image,
|
preview_image,
|
||||||
UI_DPI_FAC);
|
UI_DPI_FAC);
|
||||||
@ -570,10 +563,16 @@ static void file_draw_preview(const SpaceFile *sfile,
|
|||||||
char blend_path[FILE_MAX_LIBEXTRA];
|
char blend_path[FILE_MAX_LIBEXTRA];
|
||||||
|
|
||||||
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
|
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,
|
UI_but_drag_set_asset(but,
|
||||||
&(AssetHandle){.file_data = file},
|
&(AssetHandle){.file_data = file},
|
||||||
BLI_strdup(blend_path),
|
BLI_strdup(blend_path),
|
||||||
get_asset_import_type(sfile, file),
|
import_method,
|
||||||
icon,
|
icon,
|
||||||
imb,
|
imb,
|
||||||
scale);
|
scale);
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "AS_asset_representation.hh"
|
||||||
|
|
||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
#include "DNA_userdef_types.h"
|
#include "DNA_userdef_types.h"
|
||||||
@ -58,6 +60,7 @@
|
|||||||
#include "UI_interface_icons.h"
|
#include "UI_interface_icons.h"
|
||||||
#include "UI_view2d.h"
|
#include "UI_view2d.h"
|
||||||
|
|
||||||
|
#include "AS_asset_representation.h"
|
||||||
#include "AS_essentials_library.hh"
|
#include "AS_essentials_library.hh"
|
||||||
|
|
||||||
#include "file_intern.h"
|
#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->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.type = ASSET_LIBRARY_ALL;
|
||||||
asset_params->asset_library_ref.custom_library_index = -1;
|
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;
|
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);
|
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)
|
static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data)
|
||||||
{
|
{
|
||||||
ID *asset_id = (ID *)custom_data;
|
ID *asset_id = (ID *)custom_data;
|
||||||
|
@ -99,6 +99,17 @@ typedef enum eAssetLibraryType {
|
|||||||
ASSET_LIBRARY_CUSTOM = 100,
|
ASSET_LIBRARY_CUSTOM = 100,
|
||||||
} eAssetLibraryType;
|
} 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
|
* 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.
|
* 'Main', builtin library, project library), or a custom type as defined in the Preferences.
|
||||||
|
@ -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
|
* heavy data dependencies (e.g. the image data-blocks of a material, the mesh of an object) may
|
||||||
* be reused from an earlier append. */
|
* be reused from an earlier append. */
|
||||||
FILE_ASSET_IMPORT_APPEND_REUSE = 2,
|
FILE_ASSET_IMPORT_APPEND_REUSE = 2,
|
||||||
|
/** Default: Follow the preference setting for this asset library. */
|
||||||
|
FILE_ASSET_IMPORT_FOLLOW_PREFS = 3,
|
||||||
} eFileAssetImportType;
|
} eFileAssetImportType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -577,6 +577,9 @@ typedef struct bUserAssetLibrary {
|
|||||||
|
|
||||||
char name[64]; /* MAX_NAME */
|
char name[64]; /* MAX_NAME */
|
||||||
char path[1024]; /* FILE_MAX */
|
char path[1024]; /* FILE_MAX */
|
||||||
|
|
||||||
|
short import_method; /* eAssetImportMethod */
|
||||||
|
char _pad0[6];
|
||||||
} bUserAssetLibrary;
|
} bUserAssetLibrary;
|
||||||
|
|
||||||
typedef struct SolidLight {
|
typedef struct SolidLight {
|
||||||
|
@ -6912,6 +6912,12 @@ static void rna_def_fileselect_asset_params(BlenderRNA *brna)
|
|||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
static const EnumPropertyItem asset_import_type_items[] = {
|
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_LINK, "LINK", 0, "Link", "Import the assets as linked data-block"},
|
||||||
{FILE_ASSET_IMPORT_APPEND,
|
{FILE_ASSET_IMPORT_APPEND,
|
||||||
"APPEND",
|
"APPEND",
|
||||||
|
@ -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");
|
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_string_funcs(prop, NULL, NULL, "rna_userdef_asset_library_path_set");
|
||||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
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)
|
static void rna_def_userdef_filepaths(BlenderRNA *brna)
|
||||||
|
@ -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,
|
wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
|
||||||
const char *path,
|
const char *path,
|
||||||
int import_type);
|
int /* #eAssetImportMethod */ import_type);
|
||||||
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
|
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);
|
struct AssetMetaData *WM_drag_get_asset_meta_data(const struct wmDrag *drag, int idcode);
|
||||||
/**
|
/**
|
||||||
|
@ -1074,7 +1074,7 @@ typedef struct wmDragAsset {
|
|||||||
const char *path;
|
const char *path;
|
||||||
int id_type;
|
int id_type;
|
||||||
struct AssetMetaData *metadata;
|
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
|
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
|
||||||
* #wmDropBox.
|
* #wmDropBox.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
#include "DNA_windowmanager_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->metadata = ED_asset_handle_get_metadata(asset);
|
||||||
asset_drag->path = path;
|
asset_drag->path = path;
|
||||||
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
|
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;
|
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);
|
ViewLayer *view_layer = CTX_data_view_layer(asset_drag->evil_C);
|
||||||
View3D *view3d = CTX_wm_view3d(asset_drag->evil_C);
|
View3D *view3d = CTX_wm_view3d(asset_drag->evil_C);
|
||||||
|
|
||||||
switch ((eFileAssetImportType)asset_drag->import_type) {
|
switch (eAssetImportMethod(asset_drag->import_method)) {
|
||||||
case FILE_ASSET_IMPORT_LINK:
|
case ASSET_IMPORT_LINK:
|
||||||
return WM_file_link_datablock(
|
return WM_file_link_datablock(
|
||||||
bmain, scene, view_layer, view3d, asset_drag->path, idtype, name, flag);
|
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,
|
return WM_file_append_datablock(bmain,
|
||||||
scene,
|
scene,
|
||||||
view_layer,
|
view_layer,
|
||||||
@ -631,7 +632,7 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
|||||||
name,
|
name,
|
||||||
flag | BLO_LIBLINK_APPEND_RECURSIVE |
|
flag | BLO_LIBLINK_APPEND_RECURSIVE |
|
||||||
BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR);
|
BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR);
|
||||||
case FILE_ASSET_IMPORT_APPEND_REUSE:
|
case ASSET_IMPORT_APPEND_REUSE:
|
||||||
return WM_file_append_datablock(G_MAIN,
|
return WM_file_append_datablock(G_MAIN,
|
||||||
scene,
|
scene,
|
||||||
view_layer,
|
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);
|
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)
|
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);
|
ED_asset_handle_get_full_library_path(asset, asset_blend_path);
|
||||||
drag_asset->is_external = true;
|
drag_asset->is_external = true;
|
||||||
drag_asset->asset_data.external_info = WM_drag_create_asset_data(
|
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);
|
BLI_addtail(&drag->asset_items, drag_asset);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user