diff options
author | Hans Goudey <h.goudey@me.com> | 2022-09-16 20:54:46 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-16 20:54:46 +0300 |
commit | 4cea4f4c5f845a85dd5bc95967b5ce63296015d1 (patch) | |
tree | 9a1c85caee4d566868bebc6ca48ab1153a751fb6 /source | |
parent | 3d93525069d230c4cd355d48a99a7b8e67378db5 (diff) |
Fix: Geometry nodes crash with undefined node
The new evaluator crashes for multi-input sockets coming from undefined
nodes. The multi-input socket lazy node tries to retrieve the default
value since the undefined node never created output values. But there
is no default value stored because the socket is linked.
Differential Revision: https://developer.blender.org/D15980
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index aa684b69772..137057414d4 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -211,6 +211,28 @@ class LazyFunctionForRerouteNode : public LazyFunction { }; /** + * Lazy functions for nodes whose type cannot be found. An undefined function just outputs default + * values. It's useful to have so other parts of the conversion don't have to care about undefined + * nodes. + */ +class LazyFunctionForUndefinedNode : public LazyFunction { + public: + LazyFunctionForUndefinedNode(const bNode &node, Vector<const bNodeSocket *> &r_used_outputs) + { + debug_name_ = "Undefined"; + Vector<const bNodeSocket *> dummy_used_inputs; + Vector<lf::Input> dummy_inputs; + lazy_function_interface_from_node( + node, dummy_used_inputs, r_used_outputs, dummy_inputs, outputs_); + } + + void execute_impl(lf::Params ¶ms, const lf::Context &UNUSED(context)) const override + { + params.set_default_remaining_outputs(); + } +}; + +/** * Executes a multi-function. If all inputs are single values, the results will also be single * values. If any input is a field, the outputs will also be fields. */ @@ -773,6 +795,11 @@ struct GeometryNodesLazyFunctionGraphBuilder { *bnode); if (fn_item.fn != nullptr) { this->handle_multi_function_node(*bnode, fn_item); + break; + } + if (node_type == &NodeTypeUndefined) { + this->handle_undefined_node(*bnode); + break; } /* Nodes that don't match any of the criteria above are just ignored. */ break; @@ -966,6 +993,21 @@ struct GeometryNodesLazyFunctionGraphBuilder { mapping_->viewer_node_map.add(&bnode, &lf_node); } + void handle_undefined_node(const bNode &bnode) + { + Vector<const bNodeSocket *> used_outputs; + auto lazy_function = std::make_unique<LazyFunctionForUndefinedNode>(bnode, used_outputs); + lf::FunctionNode &lf_node = lf_graph_->add_function(*lazy_function); + lf_graph_info_->functions.append(std::move(lazy_function)); + + for (const int i : used_outputs.index_range()) { + const bNodeSocket &bsocket = *used_outputs[i]; + lf::OutputSocket &lf_socket = lf_node.output(i); + output_socket_map_.add(&bsocket, &lf_socket); + mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); + } + } + void handle_links() { for (const auto item : output_socket_map_.items()) { |