diff options
author | Jacques Lucke <jacques@blender.org> | 2020-12-18 15:28:43 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-12-18 15:28:55 +0300 |
commit | c5569ba140382015c32bd638532097ea05168607 (patch) | |
tree | 49c6930453534243e1fe5e7f7a88f1b9144e938b /source | |
parent | 79d6bd9a227f9c07b2a1c3e55d9e06d8b8306f39 (diff) |
Geometry Nodes: do not crash when there are undefined nodes
Undefined geometry nodes will just output a default value now.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 29 | ||||
-rw-r--r-- | source/blender/nodes/NOD_geometry_exec.hh | 11 |
2 files changed, 38 insertions, 2 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 6bb747fa715..bbf0c7601f5 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -300,13 +300,28 @@ class GeometryNodesEvaluator { void execute_node(const DNode &node, GeoNodeExecParams params) { const bNode &bnode = params.node(); + + /* Use the geometry-node-execute callback if it exists. */ if (bnode.typeinfo->geometry_node_execute != nullptr) { bnode.typeinfo->geometry_node_execute(params); return; } - /* Use the multi-function implementation of the node. */ - const MultiFunction &fn = *mf_by_node_.lookup(&node); + /* Use the multi-function implementation if it exists. */ + const MultiFunction *multi_function = mf_by_node_.lookup_default(&node, nullptr); + if (multi_function != nullptr) { + this->execute_multi_function_node(node, params, *multi_function); + return; + } + + /* Just output default values if no implementation exists. */ + this->execute_unknown_node(node, params); + } + + void execute_multi_function_node(const DNode &node, + GeoNodeExecParams params, + const MultiFunction &fn) + { MFContextBuilder fn_context; MFParamsBuilder fn_params{fn, 1}; Vector<GMutablePointer> input_data; @@ -341,6 +356,16 @@ class GeometryNodesEvaluator { } } + void execute_unknown_node(const DNode &node, GeoNodeExecParams params) + { + for (const DOutputSocket *socket : node.outputs()) { + if (socket->is_available()) { + const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo()); + params.set_output_by_copy(socket->identifier(), {type, type.default_value()}); + } + } + } + void forward_to_inputs(const DOutputSocket &from_socket, GMutablePointer value_to_forward) { Span<const DInputSocket *> to_sockets_all = from_socket.linked_sockets(); diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index cac04e18fc7..f278d6b4107 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -44,6 +44,7 @@ using bke::WriteAttribute; using bke::WriteAttributePtr; using fn::CPPType; using fn::GMutablePointer; +using fn::GPointer; using fn::GValueMap; class GeoNodeExecParams { @@ -123,6 +124,16 @@ class GeoNodeExecParams { output_values_.add_new_by_move(identifier, value); } + void set_output_by_copy(StringRef identifier, GPointer value) + { +#ifdef DEBUG + BLI_assert(value.type() != nullptr); + BLI_assert(value.get() != nullptr); + this->check_set_output(identifier, *value.type()); +#endif + output_values_.add_new_by_copy(identifier, value); + } + /** * Store the output value for the given socket identifier. */ |