diff options
author | Jeroen Bakker <jeroen@blender.org> | 2021-06-30 10:22:37 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2021-06-30 10:22:37 +0300 |
commit | 7573e4510346afd6db6489183316c4043454159f (patch) | |
tree | b8ee7e589ae3b2b3a526ac975b4df7566f9c4c5a | |
parent | 129798cacbd9e1cd7f94a8f0c3f8b669d89ca0dc (diff) |
Fix T89004: Undefined Geometry nodes cause a crash when connected to a Group Output node.
Patch provided by Jacques Lucke.
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 4 | ||||
-rw-r--r-- | source/blender/nodes/NOD_derived_node_tree.hh | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_node_tree_ref.hh | 13 | ||||
-rw-r--r-- | source/blender/nodes/intern/derived_node_tree.cc | 10 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_tree_ref.cc | 15 |
5 files changed, 43 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index fd3634ad278..5c0301469c3 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1381,6 +1381,10 @@ static void modifyGeometry(ModifierData *md, BKE_modifier_set_error(ctx->object, md, "Node group has cycles"); return; } + if (tree.has_undefined_nodes_or_sockets()) { + BKE_modifier_set_error(ctx->object, md, "Node group has undefined nodes or sockets"); + return; + } const NodeTreeRef &root_tree_ref = tree.root_context().tree(); Span<const NodeRef *> input_nodes = root_tree_ref.nodes_by_type("NodeGroupInput"); diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh index e294bef2ea8..c27b5e0bff9 100644 --- a/source/blender/nodes/NOD_derived_node_tree.hh +++ b/source/blender/nodes/NOD_derived_node_tree.hh @@ -170,6 +170,7 @@ class DerivedNodeTree { Span<const NodeTreeRef *> used_node_tree_refs() const; bool has_link_cycles() const; + bool has_undefined_nodes_or_sockets() const; void foreach_node(FunctionRef<void(DNode)> callback) const; std::string to_dot() const; diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh index 5795617deb0..d4805daf8f5 100644 --- a/source/blender/nodes/NOD_node_tree_ref.hh +++ b/source/blender/nodes/NOD_node_tree_ref.hh @@ -125,6 +125,7 @@ class SocketRef : NonCopyable, NonMovable { bNodeTree *btree() const; bool is_available() const; + bool is_undefined() const; void *default_value() const; template<typename T> T *default_value() const; @@ -197,6 +198,7 @@ class NodeRef : NonCopyable, NonMovable { bool is_group_output_node() const; bool is_muted() const; bool is_frame() const; + bool is_undefined() const; void *storage() const; template<typename T> T *storage() const; @@ -260,6 +262,7 @@ class NodeTreeRef : NonCopyable, NonMovable { Span<const LinkRef *> links() const; bool has_link_cycles() const; + bool has_undefined_nodes_or_sockets() const; bNodeTree *btree() const; StringRefNull name() const; @@ -417,6 +420,11 @@ inline bool SocketRef::is_available() const return (bsocket_->flag & SOCK_UNAVAIL) == 0; } +inline bool SocketRef::is_undefined() const +{ + return bsocket_->typeinfo == &NodeSocketTypeUndefined; +} + inline void *SocketRef::default_value() const { return bsocket_->default_value; @@ -554,6 +562,11 @@ inline bool NodeRef::is_frame() const return bnode_->type == NODE_FRAME; } +inline bool NodeRef::is_undefined() const +{ + return bnode_->typeinfo == &NodeTypeUndefined; +} + inline bool NodeRef::is_muted() const { return (bnode_->flag & NODE_MUTED) != 0; diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index cfa790780f2..9a3eb574bcd 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -84,6 +84,16 @@ bool DerivedNodeTree::has_link_cycles() const return false; } +bool DerivedNodeTree::has_undefined_nodes_or_sockets() const +{ + for (const NodeTreeRef *tree_ref : used_node_tree_refs_) { + if (tree_ref->has_undefined_nodes_or_sockets()) { + return true; + } + } + return false; +} + /* Calls the given callback on all nodes in the (possibly nested) derived node tree. */ void DerivedNodeTree::foreach_node(FunctionRef<void(DNode)> callback) const { diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc index e42572b9cb7..49ef1ecf9f7 100644 --- a/source/blender/nodes/intern/node_tree_ref.cc +++ b/source/blender/nodes/intern/node_tree_ref.cc @@ -346,6 +346,21 @@ bool NodeTreeRef::has_link_cycles() const return false; } +bool NodeTreeRef::has_undefined_nodes_or_sockets() const +{ + for (const NodeRef *node : nodes_by_id_) { + if (node->is_undefined()) { + return true; + } + } + for (const SocketRef *socket : sockets_by_id_) { + if (socket->is_undefined()) { + return true; + } + } + return true; +} + std::string NodeTreeRef::to_dot() const { dot::DirectedGraph digraph; |