Fix T101705: crash when connecting reroute to multi-input socket
Differential Revision: https://developer.blender.org/D16203
This commit is contained in:
parent
e5425b566d
commit
a6b83617e9
Notes:
blender-bot
2024-04-11 14:26:06 +02:00
Referenced by issue #101705, Regression: assert and crash on Connecting empty reroute node to multi socket
|
@ -792,6 +792,12 @@ void nodeChainIterBackwards(const bNodeTree *ntree,
|
|||
*/
|
||||
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
|
||||
|
||||
/**
|
||||
* A dangling reroute node is a reroute node that does *not* have a "data source", i.e. no
|
||||
* non-reroute node is connected to its input.
|
||||
*/
|
||||
bool nodeIsDanglingReroute(const struct bNodeTree *ntree, const struct bNode *node);
|
||||
|
||||
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,
|
||||
const struct bNodeSocket *from,
|
||||
const struct bNodeSocket *to);
|
||||
|
|
|
@ -2157,6 +2157,38 @@ void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userd
|
|||
}
|
||||
}
|
||||
|
||||
bool nodeIsDanglingReroute(const bNodeTree *ntree, const bNode *node)
|
||||
{
|
||||
ntree->ensure_topology_cache();
|
||||
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*ntree));
|
||||
BLI_assert(!ntree->has_available_link_cycle());
|
||||
|
||||
const bNode *iter_node = node;
|
||||
if (!iter_node->is_reroute()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const blender::Span<const bNodeLink *> links =
|
||||
iter_node->input_socket(0).directly_linked_links();
|
||||
BLI_assert(links.size() <= 1);
|
||||
if (links.is_empty()) {
|
||||
return true;
|
||||
}
|
||||
const bNodeLink &link = *links[0];
|
||||
if (!link.is_available()) {
|
||||
return false;
|
||||
}
|
||||
if (link.is_muted()) {
|
||||
return false;
|
||||
}
|
||||
iter_node = link.fromnode;
|
||||
if (!iter_node->is_reroute()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************** Add stuff ********** */
|
||||
|
||||
void nodeUniqueName(bNodeTree *ntree, bNode *node)
|
||||
|
|
|
@ -158,8 +158,9 @@ class LazyFunctionForMultiInput : public LazyFunction {
|
|||
base_type_ = get_socket_cpp_type(socket);
|
||||
BLI_assert(base_type_ != nullptr);
|
||||
BLI_assert(socket.is_multi_input());
|
||||
const bNodeTree &btree = socket.owner_tree();
|
||||
for (const bNodeLink *link : socket.directly_linked_links()) {
|
||||
if (!link->is_muted()) {
|
||||
if (!(link->is_muted() || nodeIsDanglingReroute(&btree, link->fromnode))) {
|
||||
inputs_.append({"Input", *base_type_});
|
||||
}
|
||||
}
|
||||
|
@ -1073,9 +1074,7 @@ struct GeometryNodesLazyFunctionGraphBuilder {
|
|||
|
||||
void insert_links_from_socket(const bNodeSocket &from_bsocket, lf::OutputSocket &from_lf_socket)
|
||||
{
|
||||
const bNode &from_bnode = from_bsocket.owner_node();
|
||||
if (this->is_dangling_reroute_input(from_bnode)) {
|
||||
/* Dangling reroutes should not be used as source of values. */
|
||||
if (nodeIsDanglingReroute(&btree_, &from_bsocket.owner_node())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1144,8 @@ struct GeometryNodesLazyFunctionGraphBuilder {
|
|||
if (multi_input_link == link) {
|
||||
break;
|
||||
}
|
||||
if (!multi_input_link->is_muted()) {
|
||||
if (!(multi_input_link->is_muted() ||
|
||||
nodeIsDanglingReroute(&btree_, multi_input_link->fromnode))) {
|
||||
link_index++;
|
||||
}
|
||||
}
|
||||
|
@ -1174,33 +1174,6 @@ struct GeometryNodesLazyFunctionGraphBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
bool is_dangling_reroute_input(const bNode &node)
|
||||
{
|
||||
if (!node.is_reroute()) {
|
||||
return false;
|
||||
}
|
||||
const bNode *iter_node = &node;
|
||||
/* It is guaranteed at a higher level that there are no link cycles. */
|
||||
while (true) {
|
||||
const Span<const bNodeLink *> links = iter_node->input_socket(0).directly_linked_links();
|
||||
BLI_assert(links.size() <= 1);
|
||||
if (links.is_empty()) {
|
||||
return true;
|
||||
}
|
||||
const bNodeLink &link = *links[0];
|
||||
if (!link.is_available()) {
|
||||
return false;
|
||||
}
|
||||
if (link.is_muted()) {
|
||||
return false;
|
||||
}
|
||||
iter_node = link.fromnode;
|
||||
if (!iter_node->is_reroute()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lf::OutputSocket *insert_type_conversion_if_necessary(
|
||||
lf::OutputSocket &from_socket,
|
||||
const CPPType &to_type,
|
||||
|
|
Loading…
Reference in New Issue