Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_node.h24
-rw-r--r--source/blender/blenkernel/intern/node.cc15
-rw-r--r--source/blender/editors/space_node/node_add.c20
-rw-r--r--source/blender/editors/space_node/node_edit.c24
-rw-r--r--source/blender/editors/space_node/node_group.c15
-rw-r--r--source/blender/editors/space_node/node_templates.c11
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c52
-rw-r--r--source/blender/nodes/composite/node_composite_util.c10
-rw-r--r--source/blender/nodes/composite/node_composite_util.h4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc9
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c34
-rw-r--r--source/blender/nodes/function/node_function_util.cc10
-rw-r--r--source/blender/nodes/function/node_function_util.hh1
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc10
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh4
-rw-r--r--source/blender/nodes/intern/node_common.c20
-rw-r--r--source/blender/nodes/intern/node_common.h4
-rw-r--r--source/blender/nodes/shader/node_shader_util.c18
-rw-r--r--source/blender/nodes/shader/node_shader_util.h4
-rw-r--r--source/blender/nodes/texture/node_texture_util.c10
-rw-r--r--source/blender/nodes/texture/node_texture_util.h4
21 files changed, 224 insertions, 79 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 30c76dc894c..d6c4ad037e2 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -289,10 +289,22 @@ typedef struct bNodeType {
void (*freefunc_api)(struct PointerRNA *ptr);
void (*copyfunc_api)(struct PointerRNA *ptr, const struct bNode *src_node);
- /* can this node type be added to a node tree */
- bool (*poll)(struct bNodeType *ntype, struct bNodeTree *nodetree);
- /* can this node be added to a node tree */
- bool (*poll_instance)(struct bNode *node, struct bNodeTree *nodetree);
+ /**
+ * Can this node type be added to a node tree?
+ * \param r_disabled_hint: Optional hint to display in the UI when the poll fails.
+ * The callback can set this to a static string without having to
+ * null-check it (or without setting it to null if it's not used).
+ * The caller must pass a valid `const char **` and null-initialize it
+ * when it's not just a dummy, that is, if it actually wants to access
+ * the returned disabled-hint (null-check needed!).
+ */
+ bool (*poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint);
+ /** Can this node be added to a node tree?
+ * \param r_disabled_hint: See `poll()`.
+ */
+ bool (*poll_instance)(struct bNode *node,
+ struct bNodeTree *nodetree,
+ const char **r_disabled_hint);
/* optional handling of link insertion */
void (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link);
@@ -804,7 +816,9 @@ void BKE_node_preview_set_pixel(
void nodeLabel(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
const char *nodeSocketLabel(const struct bNodeSocket *sock);
-int nodeGroupPoll(struct bNodeTree *nodetree, struct bNodeTree *grouptree);
+bool nodeGroupPoll(struct bNodeTree *nodetree,
+ struct bNodeTree *grouptree,
+ const char **r_disabled_hint);
/* Init a new node type struct with default values and callbacks */
void node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 52f6c4f93ad..02195e0d60f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -2007,7 +2007,8 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
/* do an extra poll here, because some int types are used
* for multiple node types, this helps find the desired type
*/
- if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree))) {
+ const char *disabled_hint;
+ if (ntype->type == type && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint))) {
idname = ntype->idname;
break;
}
@@ -4407,15 +4408,17 @@ static void node_type_base_defaults(bNodeType *ntype)
}
/* allow this node for any tree type */
-static bool node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(ntree))
+static bool node_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *UNUSED(ntree),
+ const char **UNUSED(disabled_hint))
{
return true;
}
/* use the basic poll function */
-static bool node_poll_instance_default(bNode *node, bNodeTree *ntree)
+static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint)
{
- return node->typeinfo->poll(node->typeinfo, ntree);
+ return node->typeinfo->poll(node->typeinfo, ntree, disabled_hint);
}
/* NOLINTNEXTLINE: readability-function-size */
@@ -4634,7 +4637,9 @@ void node_type_internal_links(bNodeType *ntype,
/* callbacks for undefined types */
-static bool node_undefined_poll(bNodeType *UNUSED(ntype), bNodeTree *UNUSED(nodetree))
+static bool node_undefined_poll(bNodeType *UNUSED(ntype),
+ bNodeTree *UNUSED(nodetree),
+ const char **UNUSED(r_disabled_hint))
{
/* this type can not be added deliberately, it's just a placeholder */
return false;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 82a315366dc..a28d467df2e 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -339,7 +339,25 @@ static bNodeTree *node_add_group_get_and_poll_group_node_tree(Main *bmain,
if (!node_group) {
return NULL;
}
- if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group)) {
+
+ const char *disabled_hint = NULL;
+ if ((node_group->type != ntree->type) || !nodeGroupPoll(ntree, node_group, &disabled_hint)) {
+ if (disabled_hint) {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Can not add node group '%s' to '%s':\n %s",
+ node_group->id.name + 2,
+ ntree->id.name + 2,
+ disabled_hint);
+ }
+ else {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Can not add node group '%s' to '%s'",
+ node_group->id.name + 2,
+ ntree->id.name + 2);
+ }
+
return NULL;
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 518f5639c93..1cbd0fd607c 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2241,13 +2241,25 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* make sure all clipboard nodes would be valid in the target tree */
bool all_nodes_valid = true;
LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
- if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) {
+ const char *disabled_hint = NULL;
+ if (!node->typeinfo->poll_instance ||
+ !node->typeinfo->poll_instance(node, ntree, &disabled_hint)) {
all_nodes_valid = false;
- BKE_reportf(op->reports,
- RPT_ERROR,
- "Cannot add node %s into node tree %s",
- node->name,
- ntree->id.name + 2);
+ if (disabled_hint) {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Cannot add node %s into node tree %s:\n %s",
+ node->name,
+ ntree->id.name + 2,
+ disabled_hint);
+ }
+ else {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Cannot add node %s into node tree %s",
+ node->name,
+ ntree->id.name + 2);
+ }
}
}
if (!all_nodes_valid) {
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index e1de4bfc21e..335e2f93ff3 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -679,8 +679,19 @@ static bool node_group_make_test_selected(bNodeTree *ntree,
/* check poll functions for selected nodes */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node_group_make_use_node(node, gnode)) {
- if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, ngroup)) {
- BKE_reportf(reports, RPT_WARNING, "Can not add node '%s' in a group", node->name);
+ const char *disabled_hint = NULL;
+ if (node->typeinfo->poll_instance &&
+ !node->typeinfo->poll_instance(node, ngroup, &disabled_hint)) {
+ if (disabled_hint) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Can not add node '%s' in a group:\n %s",
+ node->name,
+ disabled_hint);
+ }
+ else {
+ BKE_reportf(reports, RPT_WARNING, "Can not add node '%s' in a group", node->name);
+ }
ok = false;
break;
}
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 3873985d93a..54145f62895 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -330,7 +330,9 @@ static void ui_node_link_items(NodeLinkArg *arg,
int i;
for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
- if ((ngroup->type != arg->ntree->type) || !nodeGroupPoll(arg->ntree, ngroup)) {
+ const char *disabled_hint;
+ if ((ngroup->type != arg->ntree->type) ||
+ !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
continue;
}
@@ -343,7 +345,9 @@ static void ui_node_link_items(NodeLinkArg *arg,
i = 0;
for (ngroup = arg->bmain->nodetrees.first; ngroup; ngroup = ngroup->id.next) {
- if ((ngroup->type != arg->ntree->type) || !nodeGroupPoll(arg->ntree, ngroup)) {
+ const char *disabled_hint;
+ if ((ngroup->type != arg->ntree->type) ||
+ !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
continue;
}
@@ -481,7 +485,8 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
BLI_array_declare(sorted_ntypes);
NODE_TYPES_BEGIN (ntype) {
- if (!(ntype->poll && ntype->poll(ntype, ntree))) {
+ const char *disabled_hint;
+ if (!(ntype->poll && ntype->poll(ntype, ntree, &disabled_hint))) {
continue;
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index b79381ac26f..1016d31f11b 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1085,13 +1085,25 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
return NULL;
}
- if (ntype->poll && !ntype->poll(ntype, ntree)) {
- BKE_reportf(reports,
- RPT_ERROR,
- "Cannot add node of type %s to node tree '%s'",
- type,
- ntree->id.name + 2);
- return NULL;
+ const char *disabled_hint = NULL;
+ if (ntype->poll && !ntype->poll(ntype, ntree, &disabled_hint)) {
+ if (disabled_hint) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Cannot add node of type %s to node tree '%s'\n %s",
+ type,
+ ntree->id.name + 2,
+ disabled_hint);
+ return NULL;
+ }
+ else {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Cannot add node of type %s to node tree '%s'",
+ type,
+ ntree->id.name + 2);
+ return NULL;
+ }
}
node = nodeAddNode(C, ntree, type);
@@ -1531,7 +1543,7 @@ char *rna_Node_ImageUser_path(PointerRNA *ptr)
return NULL;
}
-static bool rna_Node_poll(bNodeType *ntype, bNodeTree *ntree)
+static bool rna_Node_poll(bNodeType *ntype, bNodeTree *ntree, const char **UNUSED(r_disabled_hint))
{
extern FunctionRNA rna_Node_poll_func;
@@ -1556,7 +1568,9 @@ static bool rna_Node_poll(bNodeType *ntype, bNodeTree *ntree)
return visible;
}
-static bool rna_Node_poll_instance(bNode *node, bNodeTree *ntree)
+static bool rna_Node_poll_instance(bNode *node,
+ bNodeTree *ntree,
+ const char **UNUSED(disabled_info))
{
extern FunctionRNA rna_Node_poll_instance_func;
@@ -1581,10 +1595,12 @@ static bool rna_Node_poll_instance(bNode *node, bNodeTree *ntree)
return visible;
}
-static bool rna_Node_poll_instance_default(bNode *node, bNodeTree *ntree)
+static bool rna_Node_poll_instance_default(bNode *node,
+ bNodeTree *ntree,
+ const char **disabled_info)
{
/* use the basic poll function */
- return rna_Node_poll(node->typeinfo, ntree);
+ return rna_Node_poll(node->typeinfo, ntree, disabled_info);
}
static void rna_Node_update_reg(bNodeTree *ntree, bNode *node)
@@ -3214,18 +3230,20 @@ static PointerRNA rna_NodeInternal_output_template(StructRNA *srna, int index)
static bool rna_NodeInternal_poll(StructRNA *srna, bNodeTree *ntree)
{
bNodeType *ntype = RNA_struct_blender_type_get(srna);
- return ntype && (!ntype->poll || ntype->poll(ntype, ntree));
+ const char *disabled_hint;
+ return ntype && (!ntype->poll || ntype->poll(ntype, ntree, &disabled_hint));
}
static bool rna_NodeInternal_poll_instance(bNode *node, bNodeTree *ntree)
{
bNodeType *ntype = node->typeinfo;
+ const char *disabled_hint;
if (ntype->poll_instance) {
- return ntype->poll_instance(node, ntree);
+ return ntype->poll_instance(node, ntree, &disabled_hint);
}
else {
/* fall back to basic poll function */
- return !ntype->poll || ntype->poll(ntype, ntree);
+ return !ntype->poll || ntype->poll(ntype, ntree, &disabled_hint);
}
}
@@ -3408,7 +3426,8 @@ static void rna_NodeGroup_node_tree_set(PointerRNA *ptr,
bNode *node = ptr->data;
bNodeTree *ngroup = value.data;
- if (nodeGroupPoll(ntree, ngroup)) {
+ const char *disabled_hint = NULL;
+ if (nodeGroupPoll(ntree, ngroup, &disabled_hint)) {
if (node->id) {
id_us_min(node->id);
}
@@ -3430,7 +3449,8 @@ static bool rna_NodeGroup_node_tree_poll(PointerRNA *ptr, const PointerRNA value
return false;
}
- return nodeGroupPoll(ntree, ngroup);
+ const char *disabled_hint = NULL;
+ return nodeGroupPoll(ntree, ngroup, &disabled_hint);
}
static StructRNA *rna_NodeGroup_interface_typef(PointerRNA *ptr)
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
index b6cbffea413..6cc17d8c272 100644
--- a/source/blender/nodes/composite/node_composite_util.c
+++ b/source/blender/nodes/composite/node_composite_util.c
@@ -23,9 +23,15 @@
#include "node_composite_util.h"
-bool cmp_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+bool cmp_node_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
- return STREQ(ntree->idname, "CompositorNodeTree");
+ if (!STREQ(ntree->idname, "CompositorNodeTree")) {
+ *r_disabled_hint = "Not a compositor node tree";
+ return false;
+ }
+ return true;
}
void cmp_node_update_default(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h
index 800c55df4d6..4fcccbb79f0 100644
--- a/source/blender/nodes/composite/node_composite_util.h
+++ b/source/blender/nodes/composite/node_composite_util.h
@@ -54,7 +54,9 @@ extern "C" {
#define CMP_SCALE_MAX 12000
-bool cmp_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+bool cmp_node_poll_default(struct bNodeType *ntype,
+ struct bNodeTree *ntree,
+ const char **r_disabled_info);
void cmp_node_update_default(struct bNodeTree *ntree, struct bNode *node);
void cmp_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
index c5135482ec2..d9b36924516 100644
--- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
@@ -263,7 +263,9 @@ static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree),
dest_node->storage = dest_nc;
}
-static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
if (STREQ(ntree->idname, "CompositorNodeTree")) {
Scene *scene;
@@ -276,8 +278,13 @@ static bool node_poll_cryptomatte(bNodeType *UNUSED(ntype), bNodeTree *ntree)
}
}
+ if (scene == nullptr) {
+ *r_disabled_hint =
+ "The node tree must be the compositing node tree of any scene in the file";
+ }
return scene != nullptr;
}
+ *r_disabled_hint = "Not a compositor node tree";
return false;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 53ea02ff8a7..243300b0a44 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -526,24 +526,32 @@ static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
}
}
-static bool node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+static bool node_composit_poll_rlayers(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
- if (STREQ(ntree->idname, "CompositorNodeTree")) {
- Scene *scene;
+ if (!STREQ(ntree->idname, "CompositorNodeTree")) {
+ *r_disabled_hint = "Not a compositor node tree";
+ return false;
+ }
- /* XXX ugly: check if ntree is a local scene node tree.
- * Render layers node can only be used in local scene->nodetree,
- * since it directly links to the scene.
- */
- for (scene = G.main->scenes.first; scene; scene = scene->id.next) {
- if (scene->nodetree == ntree) {
- break;
- }
+ Scene *scene;
+
+ /* XXX ugly: check if ntree is a local scene node tree.
+ * Render layers node can only be used in local scene->nodetree,
+ * since it directly links to the scene.
+ */
+ for (scene = G.main->scenes.first; scene; scene = scene->id.next) {
+ if (scene->nodetree == ntree) {
+ break;
}
+ }
- return (scene != NULL);
+ if (scene == NULL) {
+ *r_disabled_hint = "The node tree must be the compositing node tree of any scene in the file";
+ return false;
}
- return false;
+ return true;
}
static void node_composit_free_rlayers(bNode *node)
diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc
index 827572d1069..8ff8b416310 100644
--- a/source/blender/nodes/function/node_function_util.cc
+++ b/source/blender/nodes/function/node_function_util.cc
@@ -17,10 +17,16 @@
#include "node_function_util.hh"
#include "node_util.h"
-bool fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+static bool fn_node_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
/* Function nodes are only supported in simulation node trees so far. */
- return STREQ(ntree->idname, "GeometryNodeTree");
+ if (!STREQ(ntree->idname, "GeometryNodeTree")) {
+ *r_disabled_hint = "Not a geometry node tree";
+ return false;
+ }
+ return true;
}
void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
diff --git a/source/blender/nodes/function/node_function_util.hh b/source/blender/nodes/function/node_function_util.hh
index d57d1383019..9fbd6712827 100644
--- a/source/blender/nodes/function/node_function_util.hh
+++ b/source/blender/nodes/function/node_function_util.hh
@@ -38,4 +38,3 @@
void fn_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
-bool fn_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 0f725ecf211..93cada2982b 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -56,9 +56,15 @@ void update_attribute_input_socket_availabilities(bNode &node,
} // namespace blender::nodes
-bool geo_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+bool geo_node_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
- return STREQ(ntree->idname, "GeometryNodeTree");
+ if (!STREQ(ntree->idname, "GeometryNodeTree")) {
+ *r_disabled_hint = "Not a geometry node tree";
+ return false;
+ }
+ return true;
}
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index ad4f4331b6c..81092798ca1 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -36,7 +36,9 @@
void geo_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
-bool geo_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+bool geo_node_poll_default(struct bNodeType *ntype,
+ struct bNodeTree *ntree,
+ const char **r_disabled_hint);
namespace blender::nodes {
void update_attribute_input_socket_availabilities(bNode &node,
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 0b1ab85c059..7fc9f664df0 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -79,12 +79,12 @@ void node_group_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int ma
BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen);
}
-bool node_group_poll_instance(bNode *node, bNodeTree *nodetree)
+bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint)
{
- if (node->typeinfo->poll(node->typeinfo, nodetree)) {
+ if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) {
bNodeTree *grouptree = (bNodeTree *)node->id;
if (grouptree) {
- return nodeGroupPoll(nodetree, grouptree);
+ return nodeGroupPoll(nodetree, grouptree, disabled_hint);
}
return true; /* without a linked node tree, group node is always ok */
@@ -93,25 +93,27 @@ bool node_group_poll_instance(bNode *node, bNodeTree *nodetree)
return false;
}
-int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)
+bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_disabled_hint)
{
bNode *node;
- int valid = 1;
+ bool valid = true;
/* unspecified node group, generally allowed
* (if anything, should be avoided on operator level)
*/
if (grouptree == NULL) {
- return 1;
+ return true;
}
if (nodetree == grouptree) {
- return 0;
+ *r_disabled_hint = "Nesting a node group inside of itself is not allowed";
+ return false;
}
for (node = grouptree->nodes.first; node; node = node->next) {
- if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, nodetree)) {
- valid = 0;
+ if (node->typeinfo->poll_instance &&
+ !node->typeinfo->poll_instance(node, nodetree, r_disabled_hint)) {
+ valid = false;
break;
}
}
diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h
index 7aad6782640..cdb7b6897b9 100644
--- a/source/blender/nodes/intern/node_common.h
+++ b/source/blender/nodes/intern/node_common.h
@@ -32,7 +32,9 @@ extern "C" {
struct bNodeTree;
void node_group_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
-bool node_group_poll_instance(struct bNode *node, struct bNodeTree *nodetree);
+bool node_group_poll_instance(struct bNode *node,
+ struct bNodeTree *nodetree,
+ const char **r_disabled_hint);
void ntree_update_reroute_nodes(struct bNodeTree *ntree);
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 1a2405e021f..04c32574a65 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -27,14 +27,24 @@
#include "node_exec.h"
-bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+bool sh_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree, const char **r_disabled_hint)
{
- return STREQ(ntree->idname, "ShaderNodeTree");
+ if (!STREQ(ntree->idname, "ShaderNodeTree")) {
+ *r_disabled_hint = "Not a shader node tree";
+ return false;
+ }
+ return true;
}
-static bool sh_fn_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+static bool sh_fn_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
- return STREQ(ntree->idname, "ShaderNodeTree") || STREQ(ntree->idname, "GeometryNodeTree");
+ if (!STREQ(ntree->idname, "ShaderNodeTree") && !STREQ(ntree->idname, "GeometryNodeTree")) {
+ *r_disabled_hint = "Not a shader or geometry node tree";
+ return false;
+ }
+ return true;
}
void sh_node_type_base(
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index 91454c3c982..857a9914354 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -80,7 +80,9 @@
extern "C" {
#endif
-bool sh_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+bool sh_node_poll_default(struct bNodeType *ntype,
+ struct bNodeTree *ntree,
+ const char **r_disabled_hint);
void sh_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
void sh_fn_node_type_base(
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index 2091a8bf10e..570b10d6e89 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -39,9 +39,15 @@
#include "node_texture_util.h"
-bool tex_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+bool tex_node_poll_default(bNodeType *UNUSED(ntype),
+ bNodeTree *ntree,
+ const char **r_disabled_hint)
{
- return STREQ(ntree->idname, "TextureNodeTree");
+ if (!STREQ(ntree->idname, "TextureNodeTree")) {
+ *r_disabled_hint = "Not a texture node tree";
+ return false;
+ }
+ return true;
}
void tex_node_type_base(
diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h
index 74f27ef3974..8f63a1ad07d 100644
--- a/source/blender/nodes/texture/node_texture_util.h
+++ b/source/blender/nodes/texture/node_texture_util.h
@@ -106,7 +106,9 @@ typedef struct TexDelegate {
int type;
} TexDelegate;
-bool tex_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+bool tex_node_poll_default(struct bNodeType *ntype,
+ struct bNodeTree *ntree,
+ const char **r_disabled_hint);
void tex_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);