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:
authorJulian Eisel <julian@blender.org>2021-04-12 19:43:23 +0300
committerJulian Eisel <julian@blender.org>2021-04-12 19:48:22 +0300
commit2bd9f9d976560c55a15ed297032f7d73c2f101cc (patch)
treed109e1131272c799f16825ce1818aac1e79fe1fc /source/blender/nodes
parentcbd193261969c9b4e1f14297d5888bad2946600e (diff)
UI/Nodes: Improve feedback when adding node fails (e.g. on drag & drop)
This is especially useful when trying to add a node group instance, e.g. via drag & drop from the Outliner or Asset Browser. Previously this would just silently fail, with no information why. This is a source of confusion, e.g. earlier, it took me a moment to realize I was dragging a node group into itself, which failed of course. Blender should always try to help the user with useful error messages. Adds error messages like: "Nesting a node group inside of itself is not allowed", "Not a compositor node tree", etc. Adds a disabled hint return argument to node and node tree polling functions. On error the hint is reported, or could even be shown in advance (e.g. if checked via an operator poll option). Differential Revision: https://developer.blender.org/D10422 Reviewed by: Jacques Lucke
Diffstat (limited to 'source/blender/nodes')
-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
14 files changed, 101 insertions, 41 deletions
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);