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:
authorHans Goudey <h.goudey@me.com>2022-09-16 20:54:46 +0300
committerHans Goudey <h.goudey@me.com>2022-09-16 20:54:46 +0300
commit4cea4f4c5f845a85dd5bc95967b5ce63296015d1 (patch)
tree9a1c85caee4d566868bebc6ca48ab1153a751fb6 /source/blender/nodes
parent3d93525069d230c4cd355d48a99a7b8e67378db5 (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/blender/nodes')
-rw-r--r--source/blender/nodes/intern/geometry_nodes_lazy_function.cc42
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 &params, 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()) {