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:
Diffstat (limited to 'source/blender/nodes/intern')
-rw-r--r--source/blender/nodes/intern/node_common.cc161
1 files changed, 79 insertions, 82 deletions
diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index 6881145a2ae..c302b1081af 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -32,6 +32,7 @@
#include "BLI_set.hh"
#include "BLI_stack.hh"
#include "BLI_string.h"
+#include "BLI_string_ref.hh"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -50,29 +51,30 @@ using blender::Map;
using blender::MultiValueMap;
using blender::Set;
using blender::Stack;
+using blender::StringRef;
/* -------------------------------------------------------------------- */
/** \name Node Group
* \{ */
-bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
+static bNodeSocket *find_matching_socket(ListBase &sockets, StringRef identifier)
{
- LISTBASE_FOREACH (bNodeSocket *, sock, &groupnode->inputs) {
- if (STREQ(sock->identifier, identifier)) {
- return sock;
+ LISTBASE_FOREACH (bNodeSocket *, socket, &sockets) {
+ if (socket->identifier == identifier) {
+ return socket;
}
}
return nullptr;
}
+bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier)
+{
+ return find_matching_socket(groupnode->inputs, identifier);
+}
+
bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identifier)
{
- LISTBASE_FOREACH (bNodeSocket *, sock, &groupnode->outputs) {
- if (STREQ(sock->identifier, identifier)) {
- return sock;
- }
- }
- return nullptr;
+ return find_matching_socket(groupnode->outputs, identifier);
}
void node_group_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
@@ -120,86 +122,81 @@ bool nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree, const char **r_dis
return valid;
}
-/* used for both group nodes and interface nodes */
-static bNodeSocket *group_verify_socket(bNodeTree *ntree,
- bNode *gnode,
- const bNodeSocket *interface_socket,
- ListBase *verify_lb,
- eNodeSocketInOut in_out)
+static void add_new_socket_from_interface(bNodeTree &node_tree,
+ bNode &node,
+ const bNodeSocket &interface_socket,
+ const eNodeSocketInOut in_out)
{
- bNodeSocket *sock;
+ bNodeSocket *socket = nodeAddSocket(&node_tree,
+ &node,
+ in_out,
+ interface_socket.idname,
+ interface_socket.identifier,
+ interface_socket.name);
- for (sock = (bNodeSocket *)verify_lb->first; sock; sock = sock->next) {
- if (STREQ(sock->identifier, interface_socket->identifier)) {
- break;
- }
+ if (interface_socket.typeinfo->interface_init_socket) {
+ interface_socket.typeinfo->interface_init_socket(
+ &node_tree, &interface_socket, &node, socket, "interface");
}
- if (sock) {
- strcpy(sock->name, interface_socket->name);
+}
- const int mask = SOCK_HIDE_VALUE;
- sock->flag = (sock->flag & ~mask) | (interface_socket->flag & mask);
+static void update_socket_to_match_interface(bNodeTree &node_tree,
+ bNode &node,
+ bNodeSocket &socket_to_update,
+ const bNodeSocket &interface_socket)
+{
+ strcpy(socket_to_update.name, interface_socket.name);
- /* Update socket type if necessary */
- if (sock->typeinfo != interface_socket->typeinfo) {
- nodeModifySocketType(ntree, gnode, sock, interface_socket->idname);
- /* Flag the tree to make sure link validity is updated after type changes. */
- ntree->update |= NTREE_UPDATE_LINKS;
- }
+ const int mask = SOCK_HIDE_VALUE;
+ socket_to_update.flag = (socket_to_update.flag & ~mask) | (interface_socket.flag & mask);
- if (interface_socket->typeinfo->interface_verify_socket) {
- interface_socket->typeinfo->interface_verify_socket(
- ntree, interface_socket, gnode, sock, "interface");
- }
- }
- else {
- sock = nodeAddSocket(ntree,
- gnode,
- in_out,
- interface_socket->idname,
- interface_socket->identifier,
- interface_socket->name);
-
- if (interface_socket->typeinfo->interface_init_socket) {
- interface_socket->typeinfo->interface_init_socket(
- ntree, interface_socket, gnode, sock, "interface");
- }
+ /* Update socket type if necessary */
+ if (socket_to_update.typeinfo != interface_socket.typeinfo) {
+ nodeModifySocketType(&node_tree, &node, &socket_to_update, interface_socket.idname);
+ /* Flag the tree to make sure link validity is updated after type changes. */
+ node_tree.update |= NTREE_UPDATE_LINKS;
}
- /* remove from list temporarily, to distinguish from orphaned sockets */
- BLI_remlink(verify_lb, sock);
-
- return sock;
+ if (interface_socket.typeinfo->interface_verify_socket) {
+ interface_socket.typeinfo->interface_verify_socket(
+ &node_tree, &interface_socket, &node, &socket_to_update, "interface");
+ }
}
-/* used for both group nodes and interface nodes */
-static void group_verify_socket_list(bNodeTree *ntree,
- bNode *gnode,
- ListBase *iosock_lb,
- ListBase *verify_lb,
- eNodeSocketInOut in_out)
+/**
+ * Used for group nodes and group input/output nodes to update the list of input or output sockets
+ * on a node to match the provided interface. Assumes that \a verify_lb is the node's matching
+ * input or output socket list, depending on whether the node is a group input/output or a group
+ * node.
+ */
+static void group_verify_socket_list(bNodeTree &node_tree,
+ bNode &node,
+ const ListBase &interface_sockets,
+ ListBase &verify_lb,
+ const eNodeSocketInOut in_out)
{
- bNodeSocket *sock, *nextsock;
-
- /* step by step compare */
-
- bNodeSocket *iosock = (bNodeSocket *)iosock_lb->first;
- for (; iosock; iosock = iosock->next) {
- /* abusing new_sock pointer for verification here! only used inside this function */
- iosock->new_sock = group_verify_socket(ntree, gnode, iosock, verify_lb, in_out);
- }
- /* leftovers are removed */
- for (sock = (bNodeSocket *)verify_lb->first; sock; sock = nextsock) {
- nextsock = sock->next;
- nodeRemoveSocket(ntree, gnode, sock);
- }
- /* and we put back the verified sockets */
- iosock = (bNodeSocket *)iosock_lb->first;
- for (; iosock; iosock = iosock->next) {
- if (iosock->new_sock) {
- BLI_addtail(verify_lb, iosock->new_sock);
- iosock->new_sock = nullptr;
+ ListBase old_sockets = verify_lb;
+ BLI_listbase_clear(&verify_lb);
+
+ LISTBASE_FOREACH (const bNodeSocket *, interface_socket, &interface_sockets) {
+ bNodeSocket *matching_socket = find_matching_socket(old_sockets, interface_socket->identifier);
+ if (matching_socket) {
+ /* If a socket with the same identifier exists in the previous socket list, update it
+ * with the correct name, type, etc. Then move it from the old list to the new one. */
+ update_socket_to_match_interface(node_tree, node, *matching_socket, *interface_socket);
+ BLI_remlink(&old_sockets, matching_socket);
+ BLI_addtail(&verify_lb, matching_socket);
}
+ else {
+ /* If there was no socket withe the same identifier already, simply create a new socket
+ * based on the interface socket, which will already add it to the new list. */
+ add_new_socket_from_interface(node_tree, node, *interface_socket, in_out);
+ }
+ }
+
+ /* Remove leftover sockets that didn't match the node group's interface. */
+ LISTBASE_FOREACH_MUTABLE (bNodeSocket *, unused_socket, &old_sockets) {
+ nodeRemoveSocket(&node_tree, &node, unused_socket);
}
}
@@ -215,8 +212,8 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node)
}
else {
bNodeTree *ngroup = (bNodeTree *)node->id;
- group_verify_socket_list(ntree, node, &ngroup->inputs, &node->inputs, SOCK_IN);
- group_verify_socket_list(ntree, node, &ngroup->outputs, &node->outputs, SOCK_OUT);
+ group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN);
+ group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT);
}
}
@@ -499,7 +496,7 @@ void node_group_input_update(bNodeTree *ntree, bNode *node)
/* check inputs and outputs, and remove or insert them */
{
/* value_in_out inverted for interface nodes to get correct socket value_property */
- group_verify_socket_list(ntree, node, &ntree->inputs, &node->outputs, SOCK_OUT);
+ group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT);
/* add virtual extension socket */
nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", "");
@@ -597,7 +594,7 @@ void node_group_output_update(bNodeTree *ntree, bNode *node)
/* check inputs and outputs, and remove or insert them */
{
/* value_in_out inverted for interface nodes to get correct socket value_property */
- group_verify_socket_list(ntree, node, &ntree->outputs, &node->inputs, SOCK_IN);
+ group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN);
/* add virtual extension socket */
nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", "");