mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Fix T88807: crash when there are multiple links between the same sockets
This commit does two things: * Disallows creating more than one link from one socket to a multi socket input. * Properly count links if there happen to be more than one link between the same sockets. The new link counting should also be more efficient asymptotically. Differential Revision: https://developer.blender.org/D11570
This commit is contained in:
parent
4e14fe167d
commit
1fa73076ca
2 changed files with 27 additions and 18 deletions
|
|
@ -82,6 +82,7 @@
|
|||
# include "COM_compositor.h"
|
||||
#endif
|
||||
|
||||
using blender::Map;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
|
@ -1767,26 +1768,27 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void count_mutli_input_socket_links(bNodeTree *ntree, SpaceNode *snode)
|
||||
{
|
||||
Map<bNodeSocket *, int> counts;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
int &count = counts.lookup_or_add(link->tosock, 0);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
/* Count temporary links going into this socket. */
|
||||
LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
|
||||
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
|
||||
bNodeLink *link = (bNodeLink *)linkdata->data;
|
||||
if (link->tosock && (link->tosock->flag & SOCK_MULTI_INPUT)) {
|
||||
int &count = counts.lookup_or_add(link->tosock, 0);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
LISTBASE_FOREACH (struct bNodeSocket *, socket, &node->inputs) {
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
if (socket->flag & SOCK_MULTI_INPUT) {
|
||||
Set<bNodeSocket *> visited_from_sockets;
|
||||
socket->total_inputs = 0;
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
if (link->tosock == socket) {
|
||||
visited_from_sockets.add(link->fromsock);
|
||||
}
|
||||
}
|
||||
/* Count temporary links going into this socket. */
|
||||
LISTBASE_FOREACH (bNodeLinkDrag *, nldrag, &snode->runtime->linkdrag) {
|
||||
LISTBASE_FOREACH (LinkData *, linkdata, &nldrag->links) {
|
||||
bNodeLink *link = (bNodeLink *)linkdata->data;
|
||||
if (link->tosock == socket) {
|
||||
visited_from_sockets.add(link->fromsock);
|
||||
}
|
||||
}
|
||||
}
|
||||
socket->total_inputs = visited_from_sockets.size();
|
||||
socket->total_inputs = counts.lookup_default(socket, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1223,6 +1223,13 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
|
|||
if (nodeCountSocketLinks(ntree, tosock) + 1 > nodeSocketLinkLimit(tosock)) {
|
||||
nodeRemSocketLinks(ntree, tosock);
|
||||
}
|
||||
if (tosock->flag & SOCK_MULTI_INPUT) {
|
||||
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
|
||||
if (link->fromsock == fromsock && link->tosock == tosock) {
|
||||
nodeRemLink(ntree, link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue