WIP: Brush assets project #106303
|
@ -1581,7 +1581,6 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel):
|
||||||
layout.prop(active_library, "path")
|
layout.prop(active_library, "path")
|
||||||
layout.prop(active_library, "import_method", text="Import Method")
|
layout.prop(active_library, "import_method", text="Import Method")
|
||||||
layout.prop(active_library, "use_relative_path")
|
layout.prop(active_library, "use_relative_path")
|
||||||
layout.prop(active_library, "is_default")
|
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_UL_asset_libraries(UIList):
|
class USERPREF_UL_asset_libraries(UIList):
|
||||||
|
|
|
@ -89,7 +89,7 @@ static const asset_system::AssetRepresentation *get_local_asset_from_relative_id
|
||||||
return matching_asset;
|
return matching_asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const asset_system::AssetRepresentation *find_asset_from_weak_ref(
|
const asset_system::AssetRepresentation *find_asset_from_weak_ref(
|
||||||
const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
|
const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
|
||||||
{
|
{
|
||||||
if (weak_ref.asset_library_type == ASSET_LIBRARY_LOCAL) {
|
if (weak_ref.asset_library_type == ASSET_LIBRARY_LOCAL) {
|
||||||
|
|
|
@ -44,6 +44,9 @@ void operator_asset_reference_props_set(const asset_system::AssetRepresentation
|
||||||
PointerRNA &ptr);
|
PointerRNA &ptr);
|
||||||
void operator_asset_reference_props_register(StructRNA &srna);
|
void operator_asset_reference_props_register(StructRNA &srna);
|
||||||
|
|
||||||
|
const asset_system::AssetRepresentation *find_asset_from_weak_ref(
|
||||||
|
const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all asset libraries to find an asset from the #operator_asset_reference_props_register
|
* Load all asset libraries to find an asset from the #operator_asset_reference_props_register
|
||||||
* properties. The loading happens in the background, so there may be no result immediately. In
|
* properties. The loading happens in the background, so there may be no result immediately. In
|
||||||
|
|
|
@ -788,19 +788,6 @@ static AssetWeakReference brush_asset_create_weakref_hack(const bUserAssetLibrar
|
||||||
return asset_weak_ref;
|
return asset_weak_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const bUserAssetLibrary *brush_asset_get_default_library()
|
|
||||||
{
|
|
||||||
if (BLI_listbase_is_empty(&U.asset_libraries)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
LISTBASE_FOREACH (const bUserAssetLibrary *, asset_library, &U.asset_libraries) {
|
|
||||||
if (asset_library->flag & ASSET_LIBRARY_DEFAULT) {
|
|
||||||
return asset_library;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return static_cast<const bUserAssetLibrary *>(U.asset_libraries.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void refresh_asset_library(const bContext *C, const bUserAssetLibrary &user_library)
|
static void refresh_asset_library(const bContext *C, const bUserAssetLibrary &user_library)
|
||||||
{
|
{
|
||||||
/* TODO: Should the all library reference be automatically cleared? */
|
/* TODO: Should the all library reference be automatically cleared? */
|
||||||
|
@ -827,6 +814,12 @@ static bool brush_asset_save_as_poll(bContext *C)
|
||||||
if (paint == nullptr || brush == nullptr) {
|
if (paint == nullptr || brush == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!paint->brush_asset_reference) {
|
||||||
|
/* The brush should always be an imported asset. We use this asset reference to find
|
||||||
|
* which library and catalog the brush came from, as defaults for the popup. */
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (BLI_listbase_is_empty(&U.asset_libraries)) {
|
if (BLI_listbase_is_empty(&U.asset_libraries)) {
|
||||||
CTX_wm_operator_poll_msg_set(C, "No asset library available to save to");
|
CTX_wm_operator_poll_msg_set(C, "No asset library available to save to");
|
||||||
|
@ -952,17 +945,74 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op)
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::optional<AssetLibraryReference> library_to_library_ref(
|
||||||
|
const asset_system::AssetLibrary &library)
|
||||||
|
{
|
||||||
|
for (const AssetLibraryReference &ref : asset_system::all_valid_asset_library_refs()) {
|
||||||
|
const std::string root_path = AS_asset_library_root_path_from_library_ref(ref);
|
||||||
|
/* Use #BLI_path_cmp_normalized because `library.root_path()` ends with a slash while
|
||||||
|
* `root_path` doesn't. */
|
||||||
|
if (BLI_path_cmp_normalized(root_path.c_str(), library.root_path().c_str()) == 0) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool library_is_editable(const AssetLibraryReference &library)
|
||||||
|
{
|
||||||
|
if (library.type == ASSET_LIBRARY_ESSENTIALS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
static int brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||||
{
|
{
|
||||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||||
Brush *brush = BKE_paint_brush(paint);
|
Brush *brush = BKE_paint_brush(paint);
|
||||||
|
const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference;
|
||||||
|
const asset_system::AssetRepresentation *asset = asset::find_asset_from_weak_ref(
|
||||||
|
*C, brush_weak_ref, op->reports);
|
||||||
|
if (!asset) {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
const asset_system::AssetLibrary &library = asset->owner_asset_library();
|
||||||
|
const std::optional<AssetLibraryReference> library_ref = library_to_library_ref(library);
|
||||||
|
if (!library_ref) {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
RNA_string_set(op->ptr, "name", brush->id.name + 2);
|
RNA_string_set(op->ptr, "name", brush->id.name + 2);
|
||||||
|
|
||||||
if (const bUserAssetLibrary *library = brush_asset_get_default_library()) {
|
/* If the library isn't saved from the operator's last execution, find the current library or the
|
||||||
const AssetLibraryReference library_ref = user_library_to_library_ref(*library);
|
* first library if the current library isn't editable. */
|
||||||
const int enum_value = asset::library_reference_to_enum_value(&library_ref);
|
if (!RNA_struct_property_is_set_ex(op->ptr, "asset_library_reference", false)) {
|
||||||
RNA_enum_set(op->ptr, "asset_library_reference", enum_value);
|
if (library_is_editable(*library_ref)) {
|
||||||
|
RNA_enum_set(op->ptr,
|
||||||
|
"asset_library_reference",
|
||||||
|
asset::library_reference_to_enum_value(&*library_ref));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const AssetLibraryReference first_library = user_library_to_library_ref(
|
||||||
|
*static_cast<const bUserAssetLibrary *>(U.asset_libraries.first));
|
||||||
|
RNA_enum_set(op->ptr,
|
||||||
|
"asset_library_reference",
|
||||||
|
asset::library_reference_to_enum_value(&first_library));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* By default, put the new asset in the same catalog as the existing asset. */
|
||||||
|
if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) {
|
||||||
|
const asset_system::CatalogID catalog_id = asset->get_metadata().catalog_id;
|
||||||
|
const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(catalog_id);
|
||||||
|
if (catalog == nullptr) {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Save"));
|
return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Save"));
|
||||||
|
@ -990,6 +1040,7 @@ static void visit_asset_catalog_for_search_fn(
|
||||||
const char *edit_text,
|
const char *edit_text,
|
||||||
FunctionRef<void(StringPropertySearchVisitParams)> visit_fn)
|
FunctionRef<void(StringPropertySearchVisitParams)> visit_fn)
|
||||||
{
|
{
|
||||||
|
/* NOTE: Using the all library would also be a valid choice. */
|
||||||
const bUserAssetLibrary *user_library = get_asset_library_from_prop(*ptr);
|
const bUserAssetLibrary *user_library = get_asset_library_from_prop(*ptr);
|
||||||
if (!user_library) {
|
if (!user_library) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -117,7 +117,6 @@ typedef enum eAssetImportMethod {
|
||||||
|
|
||||||
typedef enum eAssetLibrary_Flag {
|
typedef enum eAssetLibrary_Flag {
|
||||||
ASSET_LIBRARY_RELATIVE_PATH = (1 << 0),
|
ASSET_LIBRARY_RELATIVE_PATH = (1 << 0),
|
||||||
ASSET_LIBRARY_DEFAULT = (1 << 1),
|
|
||||||
} eAssetLibrary_Flag;
|
} eAssetLibrary_Flag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -361,18 +361,6 @@ static void rna_userdef_asset_library_path_set(PointerRNA *ptr, const char *valu
|
||||||
BKE_preferences_asset_library_path_set(library, value);
|
BKE_preferences_asset_library_path_set(library, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_UserAssetLibrary_is_default_set(PointerRNA *ptr, bool value)
|
|
||||||
{
|
|
||||||
bUserAssetLibrary *library = static_cast<bUserAssetLibrary *>(ptr->data);
|
|
||||||
if (!value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LISTBASE_FOREACH (bUserAssetLibrary *, library_iter, &U.asset_libraries) {
|
|
||||||
library_iter->flag &= ~ASSET_LIBRARY_DEFAULT;
|
|
||||||
}
|
|
||||||
library->flag |= ASSET_LIBRARY_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rna_userdef_extension_repo_name_set(PointerRNA *ptr, const char *value)
|
static void rna_userdef_extension_repo_name_set(PointerRNA *ptr, const char *value)
|
||||||
{
|
{
|
||||||
bUserExtensionRepo *repo = (bUserExtensionRepo *)ptr->data;
|
bUserExtensionRepo *repo = (bUserExtensionRepo *)ptr->data;
|
||||||
|
@ -6618,11 +6606,6 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna)
|
||||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", ASSET_LIBRARY_RELATIVE_PATH);
|
RNA_def_property_boolean_sdna(prop, nullptr, "flag", ASSET_LIBRARY_RELATIVE_PATH);
|
||||||
RNA_def_property_ui_text(
|
RNA_def_property_ui_text(
|
||||||
prop, "Relative Path", "Use relative path when linking assets from this asset library");
|
prop, "Relative Path", "Use relative path when linking assets from this asset library");
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "is_default", PROP_BOOLEAN, PROP_NONE);
|
|
||||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", ASSET_LIBRARY_DEFAULT);
|
|
||||||
RNA_def_property_boolean_funcs(prop, nullptr, "rna_UserAssetLibrary_is_default_set");
|
|
||||||
RNA_def_property_ui_text(prop, "Default", "Use this library for saving new assets");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
||||||
|
|
Loading…
Reference in New Issue