Geometry Nodes: Expose non-asset tools
Node tools are no longer required to be assets, and they aren't assets
by default anymore. Non-assets don't have catalogs for header menu
organization, so they are only exposed in the "Unassigned" menu, which
is now just an icon so it takes less spac, makes the connection to the
asset browser, and signals more that it's not the "final" place for a
tool. Tool node groups have fake user set by default, since they don't
have users. The "Is Tool" status of a node group is configurable in the
editor N-panel, just like the modifier status.
This is similar to af3461c387, and has the same check for
whether a node group is "local."
This commit is contained in:
@@ -43,7 +43,8 @@ def geometry_node_group_empty_modifier_new(name):
|
||||
|
||||
def geometry_node_group_empty_tool_new(context):
|
||||
group = geometry_node_group_empty_new(data_("Tool"))
|
||||
group.asset_mark()
|
||||
# Node tools have fake users by default, otherwise Blender will delete them since they have no users.
|
||||
group.use_fake_user = True
|
||||
group.is_tool = True
|
||||
|
||||
ob_type = context.object.type if context.object else 'MESH'
|
||||
|
||||
@@ -163,7 +163,7 @@ class NODE_HT_header(Header):
|
||||
row.template_ID(snode, "node_tree", new="node.new_geometry_nodes_modifier")
|
||||
else:
|
||||
layout.template_ID(snode, "node_tree", new="node.new_geometry_node_group_tool")
|
||||
if snode.node_tree and snode.node_tree.asset_data:
|
||||
if snode.node_tree:
|
||||
layout.popover(panel="NODE_PT_geometry_node_tool_object_types", text="Types")
|
||||
layout.popover(panel="NODE_PT_geometry_node_tool_mode", text="Modes")
|
||||
display_pin = False
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_wrapper.hh"
|
||||
@@ -72,26 +73,38 @@ namespace blender::ed::geometry {
|
||||
/** \name Operator
|
||||
* \{ */
|
||||
|
||||
static const bNodeTree *get_node_group(const bContext &C, PointerRNA &ptr, ReportList *reports)
|
||||
static const bNodeTree *get_asset_or_local_node_group(const bContext &C,
|
||||
PointerRNA &ptr,
|
||||
ReportList *reports)
|
||||
{
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
if (bNodeTree *group = reinterpret_cast<bNodeTree *>(
|
||||
WM_operator_properties_id_lookup_from_name_or_session_uuid(&bmain, &ptr, ID_NT)))
|
||||
{
|
||||
return group;
|
||||
}
|
||||
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
asset::operator_asset_reference_props_get_asset_from_all_library(C, ptr, reports);
|
||||
if (!asset) {
|
||||
return nullptr;
|
||||
}
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
bNodeTree *node_group = reinterpret_cast<bNodeTree *>(
|
||||
asset::asset_local_id_ensure_imported(bmain, *asset));
|
||||
if (!node_group) {
|
||||
return reinterpret_cast<bNodeTree *>(asset::asset_local_id_ensure_imported(bmain, *asset));
|
||||
}
|
||||
|
||||
static const bNodeTree *get_node_group(const bContext &C, PointerRNA &ptr, ReportList *reports)
|
||||
{
|
||||
const bNodeTree *group = get_asset_or_local_node_group(C, ptr, reports);
|
||||
if (!group) {
|
||||
return nullptr;
|
||||
}
|
||||
if (node_group->type != NTREE_GEOMETRY) {
|
||||
if (group->type != NTREE_GEOMETRY) {
|
||||
if (reports) {
|
||||
BKE_report(reports, RPT_ERROR, "Asset is not a geometry node group");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return node_group;
|
||||
return group;
|
||||
}
|
||||
|
||||
class OperatorComputeContext : public ComputeContext {
|
||||
@@ -455,11 +468,16 @@ static bool run_node_ui_poll(wmOperatorType * /*ot*/, PointerRNA *ptr)
|
||||
static std::string run_node_group_get_name(wmOperatorType * /*ot*/, PointerRNA *ptr)
|
||||
{
|
||||
int len;
|
||||
char *name_c = RNA_string_get_alloc(ptr, "relative_asset_identifier", nullptr, 0, &len);
|
||||
StringRef ref(name_c, len);
|
||||
std::string name = ref.drop_prefix(ref.find_last_of('/') + 1);
|
||||
MEM_freeN(name_c);
|
||||
return name;
|
||||
char *local_name = RNA_string_get_alloc(ptr, "name", nullptr, 0, &len);
|
||||
BLI_SCOPED_DEFER([&]() { MEM_SAFE_FREE(local_name); })
|
||||
if (len > 0) {
|
||||
return std::string(local_name, len);
|
||||
}
|
||||
char *library_asset_identifier = RNA_string_get_alloc(
|
||||
ptr, "relative_asset_identifier", nullptr, 0, &len);
|
||||
BLI_SCOPED_DEFER([&]() { MEM_SAFE_FREE(library_asset_identifier); })
|
||||
StringRef ref(library_asset_identifier, len);
|
||||
return ref.drop_prefix(ref.find_last_of('/') + 1);
|
||||
}
|
||||
|
||||
void GEOMETRY_OT_execute_node_group(wmOperatorType *ot)
|
||||
@@ -479,6 +497,7 @@ void GEOMETRY_OT_execute_node_group(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
asset::operator_asset_reference_props_register(*ot->srna);
|
||||
WM_operator_properties_id_lookup(ot, true);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -672,8 +691,8 @@ static void catalog_assets_draw(const bContext *C, Menu *menu)
|
||||
}
|
||||
|
||||
catalog_item->foreach_child([&](asset_system::AssetCatalogTreeItem &item) {
|
||||
asset::draw_menu_for_catalog(
|
||||
screen, *all_library, item, "GEO_MT_node_operator_catalog_assets", *layout);
|
||||
asset::draw_menu_for_catalog(
|
||||
screen, *all_library, item, "GEO_MT_node_operator_catalog_assets", *layout);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -688,6 +707,26 @@ MenuType node_group_operator_assets_menu()
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool unassigned_local_poll(const bContext &C)
|
||||
{
|
||||
Main &bmain = *CTX_data_main(&C);
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(
|
||||
eContextObjectMode(CTX_data_mode_enum(&C)));
|
||||
|
||||
LISTBASE_FOREACH (const bNodeTree *, group, &bmain.nodetrees) {
|
||||
/* Assets are displayed in other menus, and non-local data-blocks aren't added to this menu. */
|
||||
if (group->id.library_weak_reference || group->id.asset_data) {
|
||||
continue;
|
||||
}
|
||||
if (!group->geometry_node_asset_traits ||
|
||||
(group->geometry_node_asset_traits->flag & flag) != flag) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void catalog_assets_draw_unassigned(const bContext *C, Menu *menu)
|
||||
{
|
||||
asset::AssetItemTree *tree = get_static_item_tree(*C);
|
||||
@@ -708,12 +747,45 @@ static void catalog_assets_draw_unassigned(const bContext *C, Menu *menu)
|
||||
&props_ptr);
|
||||
asset::operator_asset_reference_props_set(*asset, props_ptr);
|
||||
}
|
||||
|
||||
const GeometryNodeAssetTraitFlag flag = asset_flag_for_context(
|
||||
eContextObjectMode(CTX_data_mode_enum(C)));
|
||||
|
||||
bool add_separator = !tree->unassigned_assets.is_empty();
|
||||
Main &bmain = *CTX_data_main(C);
|
||||
LISTBASE_FOREACH (const bNodeTree *, group, &bmain.nodetrees) {
|
||||
/* Assets are displayed in other menus, and non-local data-blocks aren't added to this menu. */
|
||||
if (group->id.library_weak_reference || group->id.asset_data) {
|
||||
continue;
|
||||
}
|
||||
if (!group->geometry_node_asset_traits ||
|
||||
(group->geometry_node_asset_traits->flag & flag) != flag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (add_separator) {
|
||||
uiItemS(layout);
|
||||
uiItemL(layout, IFACE_("Non-Assets"), ICON_NONE);
|
||||
add_separator = false;
|
||||
}
|
||||
|
||||
PointerRNA props_ptr;
|
||||
uiItemFullO_ptr(layout,
|
||||
ot,
|
||||
group->id.name + 2,
|
||||
ICON_NONE,
|
||||
nullptr,
|
||||
WM_OP_INVOKE_REGION_WIN,
|
||||
UI_ITEM_NONE,
|
||||
&props_ptr);
|
||||
WM_operator_properties_id_lookup_set_from_id(&props_ptr, &group->id);
|
||||
}
|
||||
}
|
||||
|
||||
MenuType node_group_operator_assets_menu_unassigned()
|
||||
{
|
||||
MenuType type{};
|
||||
STRNCPY(type.idname, "GEO_MT_node_operator_catalog_assets_unassigned");
|
||||
STRNCPY(type.idname, "GEO_MT_node_operator_unassigned");
|
||||
type.poll = asset_menu_poll;
|
||||
type.draw = catalog_assets_draw_unassigned;
|
||||
type.listener = asset::asset_reading_region_listen_fn;
|
||||
@@ -783,11 +855,8 @@ void ui_template_node_operator_asset_root_items(uiLayout &layout, const bContext
|
||||
}
|
||||
});
|
||||
|
||||
if (!tree->unassigned_assets.is_empty()) {
|
||||
uiItemM(&layout,
|
||||
"GEO_MT_node_operator_catalog_assets_unassigned",
|
||||
IFACE_("Unassigned"),
|
||||
ICON_NONE);
|
||||
if (!tree->unassigned_assets.is_empty() || unassigned_local_poll(C)) {
|
||||
uiItemM(&layout, "GEO_MT_node_operator_unassigned", "", ICON_FILE_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user