Fix #106138: Node add searches missing context-based poll

Before the add node search refactor and link-drag-search, nodes were
filtered out based on whether they worked with the active render
engine. For example, the Principled Hair BSDF node doesn't work with
EEVEE, so it isn't displayed in the UI. While we might want to relax
this in the future, we have no better way to show that they don't work
right now, so it's best to keep that behavior.

The filtering is implemented with a new node type callback, mainly
to reduce the boilerplate of implementing many node search callbacks
otherwise. It's also relatively clear this way I think. The only
downside is that now there are three poll functions.

I didn't port the "eevee_cycles_shader_nodes_poll" to the new
searches, since I don't understand the purpose of it.

Pull Request: https://projects.blender.org/blender/blender/pulls/106829
This commit is contained in:
Hans Goudey
2023-04-19 15:48:18 +02:00
committed by Hans Goudey
parent 91a29c9b9a
commit d6abd2ce72
28 changed files with 89 additions and 3 deletions

View File

@@ -298,6 +298,12 @@ typedef struct bNodeType {
void (*freefunc_api)(struct PointerRNA *ptr);
void (*copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node);
/**
* An additional poll test for deciding whether nodes should be an option in search menus.
* Potentially more strict poll than #poll(), but doesn't have to check the same things.
*/
bool (*add_ui_poll)(const struct bContext *C);
/**
* Can this node type be added to a node tree?
* \param r_disabled_hint: Hint to display in the UI when the poll fails.

View File

@@ -161,11 +161,14 @@ static void gather_add_node_operations(const bContext &C,
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
}
if (!(node_type->add_ui_poll && node_type->add_ui_poll(&C))) {
continue;
}
if (!node_type->gather_add_node_search_ops) {
continue;
}
Vector<nodes::AddNodeInfo> info_items;
nodes::GatherAddNodeSearchParams params(*node_type, node_tree, info_items);
nodes::GatherAddNodeSearchParams params(C, *node_type, node_tree, info_items);
node_type->gather_add_node_search_ops(params);
for (nodes::AddNodeInfo &info : info_items) {
AddNodeItem item{};

View File

@@ -288,6 +288,9 @@ static void gather_socket_link_operations(const bContext &C,
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
}
if (!(node_type->add_ui_poll && node_type->add_ui_poll(&C))) {
continue;
}
if (StringRefNull(node_type->ui_name).endswith("(Legacy)")) {
continue;
}

View File

@@ -25,18 +25,25 @@ struct AddNodeInfo {
};
class GatherAddNodeSearchParams {
const bContext &C_;
const bNodeType &node_type_;
const bNodeTree &node_tree_;
Vector<AddNodeInfo> &r_items;
public:
GatherAddNodeSearchParams(const bNodeType &node_type,
GatherAddNodeSearchParams(const bContext &C,
const bNodeType &node_type,
const bNodeTree &node_tree,
Vector<AddNodeInfo> &r_items)
: node_type_(node_type), node_tree_(node_tree), r_items(r_items)
: C_(C), node_type_(node_type), node_tree_(node_tree), r_items(r_items)
{
}
const bContext &context() const
{
return C_;
}
const bNodeTree &node_tree() const
{
return node_tree_;

View File

@@ -6,7 +6,9 @@
*/
#include "DNA_node_types.h"
#include "DNA_space_types.h"
#include "BKE_context.h"
#include "BKE_node_runtime.hh"
#include "node_shader_util.hh"
@@ -14,6 +16,8 @@
#include "NOD_add_node_search.hh"
#include "NOD_socket_search_link.hh"
#include "RE_engine.h"
#include "node_exec.h"
bool sh_node_poll_default(const bNodeType * /*ntype*/,
@@ -56,6 +60,42 @@ void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nc
ntype->gather_add_node_search_ops = blender::nodes::search_node_add_ops_for_basic_node;
}
bool line_style_shader_nodes_poll(const bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
return snode->shaderfrom == SNODE_SHADER_LINESTYLE;
}
bool world_shader_nodes_poll(const bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
return snode->shaderfrom == SNODE_SHADER_WORLD;
}
bool object_shader_nodes_poll(const bContext *C)
{
const SpaceNode *snode = CTX_wm_space_node(C);
return snode->shaderfrom == SNODE_SHADER_OBJECT;
}
bool object_cycles_shader_nodes_poll(const bContext *C)
{
if (!object_shader_nodes_poll(C)) {
return false;
}
const RenderEngineType *engine_type = CTX_data_engine_type(C);
return STREQ(engine_type->idname, "CYCLES");
}
bool object_eevee_shader_nodes_poll(const bContext *C)
{
if (!object_shader_nodes_poll(C)) {
return false;
}
const RenderEngineType *engine_type = CTX_data_engine_type(C);
return STREQ(engine_type->idname, "BLENDER_EEVEE");
}
/* ****** */
static void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)

View File

@@ -68,6 +68,11 @@ bool sh_node_poll_default(const struct bNodeType *ntype,
const char **r_disabled_hint);
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass);
void sh_fn_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass);
bool line_style_shader_nodes_poll(const struct bContext *C);
bool world_shader_nodes_poll(const struct bContext *C);
bool object_shader_nodes_poll(const struct bContext *C);
bool object_cycles_shader_nodes_poll(const struct bContext *C);
bool object_eevee_shader_nodes_poll(const struct bContext *C);
/* ********* exec data struct, remains internal *********** */

View File

@@ -33,6 +33,7 @@ void register_node_type_sh_background()
sh_node_type_base(&ntype, SH_NODE_BACKGROUND, "Background", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = world_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_background;
nodeRegisterType(&ntype);

View File

@@ -67,6 +67,7 @@ void register_node_type_sh_bsdf_anisotropic()
sh_node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_anisotropic;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.initfunc = file_ns::node_shader_init_anisotropic;

View File

@@ -44,6 +44,7 @@ void register_node_type_sh_bsdf_diffuse()
sh_node_type_base(&ntype, SH_NODE_BSDF_DIFFUSE, "Diffuse BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_diffuse;

View File

@@ -56,6 +56,7 @@ void register_node_type_sh_bsdf_glass()
sh_node_type_base(&ntype, SH_NODE_BSDF_GLASS, "Glass BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.initfunc = file_ns::node_shader_init_glass;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glass;

View File

@@ -55,6 +55,7 @@ void register_node_type_sh_bsdf_glossy()
sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.initfunc = file_ns::node_shader_init_glossy;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glossy;

View File

@@ -56,6 +56,7 @@ void register_node_type_sh_bsdf_hair()
sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR, "Hair BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_hair;
node_type_size(&ntype, 150, 60, 200);
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_hair;

View File

@@ -127,6 +127,7 @@ void register_node_type_sh_bsdf_hair_principled()
sh_node_type_base(
&ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_principled_hair;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
ntype.initfunc = file_ns::node_shader_init_hair_principled;

View File

@@ -245,6 +245,7 @@ void register_node_type_sh_bsdf_principled()
sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_principled;
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
ntype.initfunc = file_ns::node_shader_init_principled;

View File

@@ -54,6 +54,7 @@ void register_node_type_sh_bsdf_refraction()
sh_node_type_base(&ntype, SH_NODE_BSDF_REFRACTION, "Refraction BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.initfunc = file_ns::node_shader_init_refraction;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_refraction;

View File

@@ -57,6 +57,7 @@ void register_node_type_sh_bsdf_toon()
sh_node_type_base(&ntype, SH_NODE_BSDF_TOON, "Toon BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_toon;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_toon;

View File

@@ -39,6 +39,7 @@ void register_node_type_sh_bsdf_translucent()
sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSLUCENT, "Translucent BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_translucent;
nodeRegisterType(&ntype);

View File

@@ -34,6 +34,7 @@ void register_node_type_sh_bsdf_transparent()
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_BSDF_TRANSPARENT, "Transparent BSDF", NODE_CLASS_SHADER);
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_transparent;

View File

@@ -43,6 +43,7 @@ void register_node_type_sh_bsdf_velvet()
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_BSDF_VELVET, "Velvet BSDF", NODE_CLASS_SHADER);
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_velvet;

View File

@@ -80,6 +80,7 @@ void register_node_type_sh_eevee_specular()
sh_node_type_base(&ntype, SH_NODE_EEVEE_SPECULAR, "Specular BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_eevee_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_eevee_specular;
nodeRegisterType(&ntype);

View File

@@ -30,6 +30,7 @@ void register_node_type_sh_holdout()
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_HOLDOUT, "Holdout", NODE_CLASS_SHADER);
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.declare = file_ns::node_declare;
ntype.gpu_fn = file_ns::gpu_shader_rgb;

View File

@@ -37,6 +37,7 @@ void register_node_type_sh_output_light()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_LIGHT, "Light Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_output_light;
ntype.no_muting = true;

View File

@@ -49,6 +49,7 @@ void register_node_type_sh_output_linestyle()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_LINESTYLE, "Line Style Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = line_style_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_buts_output_linestyle;
ntype.no_muting = true;

View File

@@ -54,6 +54,7 @@ void register_node_type_sh_output_material()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_MATERIAL, "Material Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_output_material;
ntype.no_muting = true;

View File

@@ -41,6 +41,7 @@ void register_node_type_sh_output_world()
sh_node_type_base(&ntype, SH_NODE_OUTPUT_WORLD, "World Output", NODE_CLASS_OUTPUT);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = world_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_output_world;
ntype.no_muting = true;

View File

@@ -34,6 +34,7 @@ void register_node_type_sh_shadertorgb()
sh_node_type_base(&ntype, SH_NODE_SHADERTORGB, "Shader to RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_eevee_shader_nodes_poll;
ntype.gpu_fn = file_ns::node_shader_gpu_shadertorgb;
nodeRegisterType(&ntype);

View File

@@ -87,6 +87,7 @@ void register_node_type_sh_subsurface_scattering()
sh_node_type_base(
&ntype, SH_NODE_SUBSURFACE_SCATTERING, "Subsurface Scattering", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_subsurface;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
ntype.initfunc = file_ns::node_shader_init_subsurface_scattering;

View File

@@ -29,6 +29,7 @@ void register_node_type_sh_uvalongstroke()
sh_node_type_base(&ntype, SH_NODE_UVALONGSTROKE, "UV Along Stroke", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = line_style_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_uvalongstroke;
nodeRegisterType(&ntype);