Refactor: Retrieve node operator asset with property #110018

Merged
Hans Goudey merged 11 commits from HooglyBoogly/blender:node-group-operator-path-prop into main 2023-08-01 14:55:07 +02:00
5 changed files with 142 additions and 28 deletions

View File

@ -166,6 +166,8 @@ class AssetLibrary {
*/
AssetIdentifier asset_identifier_from_library(StringRef relative_asset_path);
std::string resolve_asset_weak_reference_to_full_path(const AssetWeakReference &asset_reference);
eAssetLibraryType library_type() const;
StringRefNull name() const;
StringRefNull root_path() const;

View File

@ -302,6 +302,13 @@ AssetIdentifier AssetLibrary::asset_identifier_from_library(StringRef relative_a
return AssetIdentifier(root_path_, relative_asset_path);
}
std::string AssetLibrary::resolve_asset_weak_reference_to_full_path(
const AssetWeakReference &asset_reference)
{
AssetLibraryService *service = AssetLibraryService::get();
return service->resolve_asset_weak_reference_to_full_path(asset_reference);
}
void AssetLibrary::refresh_catalog_simplename(AssetMetaData *asset_data)
{
if (BLI_uuid_is_nil(asset_data->catalog_id)) {

View File

@ -39,6 +39,7 @@
#include "DEG_depsgraph_query.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "UI_interface.h"
@ -69,9 +70,92 @@ namespace blender::ed::geometry {
/** \name Operator
* \{ */
static const bNodeTree *get_node_group(const bContext &C)
/**
* #AssetLibrary::resolve_asset_weak_reference_to_full_path() currently does not support local
* assets.
*/
static const asset_system::AssetRepresentation *get_local_asset_from_relative_identifier(
const bContext &C, const StringRefNull relative_identifier, ReportList *reports)
{
const asset_system::AssetRepresentation *asset = CTX_wm_asset(&C);
AssetLibraryReference library_ref{};
library_ref.type = ASSET_LIBRARY_LOCAL;
ED_assetlist_storage_fetch(&library_ref, &C);
ED_assetlist_ensure_previews_job(&library_ref, &C);
const asset_system::AssetRepresentation *matching_asset = nullptr;
ED_assetlist_iterate(library_ref, [&](asset_system::AssetRepresentation &asset) {
if (asset.get_identifier().library_relative_identifier() == relative_identifier) {
matching_asset = &asset;
return false;
}
return true;
});
if (reports && !matching_asset) {
if (ED_assetlist_is_loaded(&library_ref)) {
BKE_reportf(
reports, RPT_ERROR, "No asset found at path \"%s\"", relative_identifier.c_str());
}
else {
BKE_report(reports, RPT_WARNING, "Asset loading is unfinished");
}
}
return matching_asset;
}
static const asset_system::AssetRepresentation *find_asset_from_weak_ref(
const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports)
{
if (weak_ref.asset_library_type == ASSET_LIBRARY_LOCAL) {
return get_local_asset_from_relative_identifier(
C, weak_ref.relative_asset_identifier, reports);
}
const AssetLibraryReference library_ref = asset_system::all_library_reference();
ED_assetlist_storage_fetch(&library_ref, &C);
ED_assetlist_ensure_previews_job(&library_ref, &C);
asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(
asset_system::all_library_reference());
if (!all_library) {
BKE_report(reports, RPT_WARNING, "Asset loading is unfinished");
}
const std::string full_path = all_library->resolve_asset_weak_reference_to_full_path(weak_ref);
const asset_system::AssetRepresentation *matching_asset = nullptr;
ED_assetlist_iterate(library_ref, [&](asset_system::AssetRepresentation &asset) {
if (asset.get_identifier().full_path() == full_path) {
matching_asset = &asset;
return false;
}
return true;
});
if (reports && !matching_asset) {
if (ED_assetlist_is_loaded(&library_ref)) {
BKE_reportf(reports, RPT_ERROR, "No asset found at path \"%s\"", full_path.c_str());
}
}
return matching_asset;
}
/** \note Does not check asset type or meta data. */
static const asset_system::AssetRepresentation *get_asset(const bContext &C,
PointerRNA &ptr,
ReportList *reports)
{
AssetWeakReference weak_ref{};
weak_ref.asset_library_type = RNA_enum_get(&ptr, "asset_library_type");
weak_ref.asset_library_identifier = RNA_string_get_alloc(
&ptr, "asset_library_identifier", nullptr, 0, nullptr);
weak_ref.relative_asset_identifier = RNA_string_get_alloc(
&ptr, "relative_asset_identifier", nullptr, 0, nullptr);
return find_asset_from_weak_ref(C, weak_ref, reports);
}
static const bNodeTree *get_node_group(const bContext &C, PointerRNA &ptr, ReportList *reports)
{
const asset_system::AssetRepresentation *asset = get_asset(C, ptr, reports);
if (!asset) {
return nullptr;
}
@ -82,6 +166,9 @@ static const bNodeTree *get_node_group(const bContext &C)
return nullptr;
}
if (node_group->type != NTREE_GEOMETRY) {
if (reports) {
BKE_report(reports, RPT_ERROR, "Asset is not a geometry node group");
}
return nullptr;
}
return node_group;
@ -217,7 +304,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
}
const eObjectMode mode = eObjectMode(active_object->mode);
const bNodeTree *node_tree = get_node_group(*C);
const bNodeTree *node_tree = get_node_group(*C, *op->ptr, op->reports);
if (!node_tree) {
return OPERATOR_CANCELLED;
}
@ -268,7 +355,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
static int run_node_group_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
const bNodeTree *node_tree = get_node_group(*C);
const bNodeTree *node_tree = get_node_group(*C, *op->ptr, op->reports);
if (!node_tree) {
return OPERATOR_CANCELLED;
}
@ -279,11 +366,9 @@ static int run_node_group_invoke(bContext *C, wmOperator *op, const wmEvent * /*
return run_node_group_exec(C, op);
}
static char *run_node_group_get_description(bContext *C,
wmOperatorType * /*ot*/,
PointerRNA * /*ptr*/)
static char *run_node_group_get_description(bContext *C, wmOperatorType * /*ot*/, PointerRNA *ptr)
{
const asset_system::AssetRepresentation *asset = CTX_wm_asset(C);
const asset_system::AssetRepresentation *asset = get_asset(*C, *ptr, nullptr);
if (!asset) {
return nullptr;
}
@ -294,34 +379,33 @@ static char *run_node_group_get_description(bContext *C,
return BLI_strdup(description);
}
static bool run_node_group_poll(bContext *C)
{
const asset_system::AssetRepresentation *asset = CTX_wm_asset(C);
if (!asset) {
return false;
}
const Object *object = CTX_data_active_object(C);
if (object->type != OB_CURVES) {
return false;
}
if (object->mode != OB_MODE_SCULPT_CURVES) {
return false;
}
return true;
}
void GEOMETRY_OT_execute_node_group(wmOperatorType *ot)
{
ot->name = "Run Node Group";
ot->idname = __func__;
ot->description = "Execute a node group on geometry";
ot->poll = run_node_group_poll;
/* A proper poll is not possible, since it doesn't have access to the operator's properties. */
ot->invoke = run_node_group_invoke;
ot->exec = run_node_group_exec;
ot->get_description = run_node_group_get_description;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
PropertyRNA *prop;
prop = RNA_def_enum(ot->srna,
"asset_library_type",
rna_enum_aset_library_type_items,
ASSET_LIBRARY_LOCAL,
"Asset Library Type",
"");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_string(
ot->srna, "asset_library_identifier", nullptr, 0, "Asset Library Identifier", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_string(
ot->srna, "relative_asset_identifier", nullptr, 0, "Relative Asset Identifier", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/** \} */
@ -430,9 +514,20 @@ static void node_add_catalog_assets_draw(const bContext *C, Menu *menu)
for (const asset_system::AssetRepresentation *asset : assets) {
uiLayout *col = uiLayoutColumn(layout, false);
PointerRNA asset_ptr = asset::create_asset_rna_ptr(asset);
uiLayoutSetContextPointer(col, "asset", &asset_ptr);
uiItemO(col, IFACE_(asset->get_name().c_str()), ICON_NONE, "GEOMETRY_OT_execute_node_group");
wmOperatorType *ot = WM_operatortype_find("GEOMETRY_OT_execute_node_group", true);
const std::unique_ptr<AssetWeakReference> weak_ref = asset->make_weak_reference();
PointerRNA props_ptr;
uiItemFullO_ptr(col,
ot,
IFACE_(asset->get_name().c_str()),
ICON_NONE,
nullptr,
WM_OP_INVOKE_DEFAULT,
eUI_Item_Flag(0),
&props_ptr);
RNA_enum_set(&props_ptr, "asset_library_type", weak_ref->asset_library_type);
RNA_string_set(&props_ptr, "asset_library_identifier", weak_ref->asset_library_identifier);
RNA_string_set(&props_ptr, "relative_asset_identifier", weak_ref->relative_asset_identifier);
}
asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(

View File

@ -258,6 +258,8 @@ DEF_ENUM(rna_enum_nla_mode_extend_items)
DEF_ENUM(rna_enum_nla_mode_blend_items)
DEF_ENUM(rna_enum_keyblock_type_items)
DEF_ENUM(rna_enum_aset_library_type_items)
#endif
#undef DEF_ENUM

View File

@ -17,6 +17,14 @@
#include "rna_internal.h"
const EnumPropertyItem rna_enum_aset_library_type_items[] = {
{ASSET_LIBRARY_LOCAL, "LOCAL", 0, "Local", ""},
{ASSET_LIBRARY_ALL, "ALL", 0, "All", ""},
{ASSET_LIBRARY_ESSENTIALS, "ESSENTIALS", 0, "Essentials", ""},
{ASSET_LIBRARY_CUSTOM, "CUSTOM", 0, "Custom", ""},
{0, nullptr, 0, nullptr, nullptr},
};
#ifdef RNA_RUNTIME
# include "AS_asset_library.h"