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:
authorJeroen Bakker <jeroen@blender.org>2021-06-30 10:22:37 +0300
committerJeroen Bakker <jeroen@blender.org>2021-06-30 10:22:37 +0300
commit7573e4510346afd6db6489183316c4043454159f (patch)
treeb8ee7e589ae3b2b3a526ac975b4df7566f9c4c5a
parent129798cacbd9e1cd7f94a8f0c3f8b669d89ca0dc (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.cc4
-rw-r--r--source/blender/nodes/NOD_derived_node_tree.hh1
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh13
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc10
-rw-r--r--source/blender/nodes/intern/node_tree_ref.cc15
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;