diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/nodes/intern | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/nodes/intern')
-rw-r--r-- | source/blender/nodes/intern/node_common.c | 773 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_common.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_exec.c | 451 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_exec.h | 54 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.c | 748 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_util.c | 530 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_util.h | 45 |
7 files changed, 1339 insertions, 1263 deletions
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 88fdc53c856..d9ea6425b01 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -43,280 +43,280 @@ #include "NOD_common.h" enum { - REFINE_FORWARD = 1 << 0, - REFINE_BACKWARD = 1 << 1, + REFINE_FORWARD = 1 << 0, + REFINE_BACKWARD = 1 << 1, }; /**** Group ****/ bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier) { - bNodeSocket *sock; - for (sock = groupnode->inputs.first; sock; sock = sock->next) - if (STREQ(sock->identifier, identifier)) - return sock; - return NULL; + bNodeSocket *sock; + for (sock = groupnode->inputs.first; sock; sock = sock->next) + if (STREQ(sock->identifier, identifier)) + return sock; + return NULL; } bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identifier) { - bNodeSocket *sock; - for (sock = groupnode->outputs.first; sock; sock = sock->next) - if (STREQ(sock->identifier, identifier)) - return sock; - return NULL; + bNodeSocket *sock; + for (sock = groupnode->outputs.first; sock; sock = sock->next) + if (STREQ(sock->identifier, identifier)) + return sock; + return NULL; } /* groups display their internal tree name as label */ void node_group_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen); + BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen); } bool node_group_poll_instance(bNode *node, bNodeTree *nodetree) { - if (node->typeinfo->poll(node->typeinfo, nodetree)) { - bNodeTree *grouptree = (bNodeTree *)node->id; - if (grouptree) - return nodeGroupPoll(nodetree, grouptree); - else - return true; /* without a linked node tree, group node is always ok */ - } - else - return false; + if (node->typeinfo->poll(node->typeinfo, nodetree)) { + bNodeTree *grouptree = (bNodeTree *)node->id; + if (grouptree) + return nodeGroupPoll(nodetree, grouptree); + else + return true; /* without a linked node tree, group node is always ok */ + } + else + return false; } int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree) { - bNode *node; - int valid = 1; - - /* unspecified node group, generally allowed - * (if anything, should be avoided on operator level) - */ - if (grouptree == NULL) - return 1; - - if (nodetree == grouptree) - return 0; - - for (node = grouptree->nodes.first; node; node = node->next) { - if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, nodetree)) { - valid = 0; - break; - } - } - return valid; + bNode *node; + int valid = 1; + + /* unspecified node group, generally allowed + * (if anything, should be avoided on operator level) + */ + if (grouptree == NULL) + return 1; + + if (nodetree == grouptree) + return 0; + + for (node = grouptree->nodes.first; node; node = node->next) { + if (node->typeinfo->poll_instance && !node->typeinfo->poll_instance(node, nodetree)) { + valid = 0; + break; + } + } + return valid; } /* used for both group nodes and interface nodes */ -static bNodeSocket *group_verify_socket(bNodeTree *ntree, bNode *gnode, bNodeSocket *iosock, ListBase *verify_lb, int in_out) +static bNodeSocket *group_verify_socket( + bNodeTree *ntree, bNode *gnode, bNodeSocket *iosock, ListBase *verify_lb, int in_out) { - bNodeSocket *sock; + bNodeSocket *sock; - for (sock = verify_lb->first; sock; sock = sock->next) { - if (STREQ(sock->identifier, iosock->identifier)) - break; - } - if (sock) { - strcpy(sock->name, iosock->name); + for (sock = verify_lb->first; sock; sock = sock->next) { + if (STREQ(sock->identifier, iosock->identifier)) + break; + } + if (sock) { + strcpy(sock->name, iosock->name); - if (iosock->typeinfo->interface_verify_socket) - iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface"); - } - else { - sock = nodeAddSocket(ntree, gnode, in_out, iosock->idname, iosock->identifier, iosock->name); + if (iosock->typeinfo->interface_verify_socket) + iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface"); + } + else { + sock = nodeAddSocket(ntree, gnode, in_out, iosock->idname, iosock->identifier, iosock->name); - if (iosock->typeinfo->interface_init_socket) - iosock->typeinfo->interface_init_socket(ntree, iosock, gnode, sock, "interface"); - } + if (iosock->typeinfo->interface_init_socket) + iosock->typeinfo->interface_init_socket(ntree, iosock, gnode, sock, "interface"); + } - /* remove from list temporarily, to distinguish from orphaned sockets */ - BLI_remlink(verify_lb, sock); + /* remove from list temporarily, to distinguish from orphaned sockets */ + BLI_remlink(verify_lb, sock); - return sock; + return sock; } /* used for both group nodes and interface nodes */ -static void group_verify_socket_list(bNodeTree *ntree, bNode *gnode, - ListBase *iosock_lb, ListBase *verify_lb, int in_out) +static void group_verify_socket_list( + bNodeTree *ntree, bNode *gnode, ListBase *iosock_lb, ListBase *verify_lb, int in_out) { - bNodeSocket *iosock, *sock, *nextsock; - - /* step by step compare */ - - iosock = 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 = verify_lb->first; sock; sock = nextsock) { - nextsock = sock->next; - nodeRemoveSocket(ntree, gnode, sock); - } - /* and we put back the verified sockets */ - iosock = iosock_lb->first; - for (; iosock; iosock = iosock->next) { - if (iosock->new_sock) { - BLI_addtail(verify_lb, iosock->new_sock); - iosock->new_sock = NULL; - } - } + bNodeSocket *iosock, *sock, *nextsock; + + /* step by step compare */ + + iosock = 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 = verify_lb->first; sock; sock = nextsock) { + nextsock = sock->next; + nodeRemoveSocket(ntree, gnode, sock); + } + /* and we put back the verified sockets */ + iosock = iosock_lb->first; + for (; iosock; iosock = iosock->next) { + if (iosock->new_sock) { + BLI_addtail(verify_lb, iosock->new_sock); + iosock->new_sock = NULL; + } + } } /* make sure all group node in ntree, which use ngroup, are sync'd */ void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *id) { - /* check inputs and outputs, and remove or insert them */ - if (id == node->id) { - if (id == NULL) { - nodeRemoveAllSockets(ntree, 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); - } - } + /* check inputs and outputs, and remove or insert them */ + if (id == node->id) { + if (id == NULL) { + nodeRemoveAllSockets(ntree, 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); + } + } } /**** FRAME ****/ static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node) { - NodeFrame *data = (NodeFrame *)MEM_callocN(sizeof(NodeFrame), "frame node storage"); - node->storage = data; + NodeFrame *data = (NodeFrame *)MEM_callocN(sizeof(NodeFrame), "frame node storage"); + node->storage = data; - data->flag |= NODE_FRAME_SHRINK; + data->flag |= NODE_FRAME_SHRINK; - data->label_size = 20; + data->label_size = 20; } void register_node_type_frame(void) { - /* frame type is used for all tree types, needs dynamic allocation */ - bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type"); + /* frame type is used for all tree types, needs dynamic allocation */ + bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type"); - node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT, NODE_BACKGROUND); - node_type_init(ntype, node_frame_init); - node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage); - node_type_size(ntype, 150, 100, 0); + node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT, NODE_BACKGROUND); + node_type_init(ntype, node_frame_init); + node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage); + node_type_size(ntype, 150, 100, 0); - ntype->needs_free = 1; - nodeRegisterType(ntype); + ntype->needs_free = 1; + nodeRegisterType(ntype); } - /* **************** REROUTE ******************** */ /* simple, only a single input and output here */ static void node_reroute_update_internal_links(bNodeTree *ntree, bNode *node) { - bNodeLink *link; - - /* Security check! */ - if (!ntree) - return; - - link = MEM_callocN(sizeof(bNodeLink), "internal node link"); - link->fromnode = node; - link->fromsock = node->inputs.first; - link->tonode = node; - link->tosock = node->outputs.first; - /* internal link is always valid */ - link->flag |= NODE_LINK_VALID; - BLI_addtail(&node->internal_links, link); + bNodeLink *link; + + /* Security check! */ + if (!ntree) + return; + + link = MEM_callocN(sizeof(bNodeLink), "internal node link"); + link->fromnode = node; + link->fromsock = node->inputs.first; + link->tonode = node; + link->tosock = node->outputs.first; + /* internal link is always valid */ + link->flag |= NODE_LINK_VALID; + BLI_addtail(&node->internal_links, link); } static void node_reroute_init(bNodeTree *ntree, bNode *node) { - /* Note: Cannot use socket templates for this, since it would reset the socket type - * on each file read via the template verification procedure. - */ - nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Input", "Input"); - nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_RGBA, PROP_NONE, "Output", "Output"); + /* Note: Cannot use socket templates for this, since it would reset the socket type + * on each file read via the template verification procedure. + */ + nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "Input", "Input"); + nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_RGBA, PROP_NONE, "Output", "Output"); } void register_node_type_reroute(void) { - /* frame type is used for all tree types, needs dynamic allocation */ - bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type"); + /* frame type is used for all tree types, needs dynamic allocation */ + bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "frame node type"); - node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0); - node_type_init(ntype, node_reroute_init); - node_type_internal_links(ntype, node_reroute_update_internal_links); + node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT, 0); + node_type_init(ntype, node_reroute_init); + node_type_internal_links(ntype, node_reroute_update_internal_links); - ntype->needs_free = 1; - nodeRegisterType(ntype); + ntype->needs_free = 1; + nodeRegisterType(ntype); } static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, int flag) { - bNodeSocket *input = node->inputs.first; - bNodeSocket *output = node->outputs.first; - bNodeLink *link; - int type = SOCK_FLOAT; - const char *type_idname = nodeStaticSocketType(type, PROP_NONE); - - /* XXX it would be a little bit more efficient to restrict actual updates - * to rerout nodes connected to an updated node, but there's no reliable flag - * to indicate updated nodes (node->update is not set on linking). - */ - - node->done = 1; - - /* recursive update */ - for (link = ntree->links.first; link; link = link->next) { - bNode *fromnode = link->fromnode; - bNode *tonode = link->tonode; - if (!tonode || !fromnode) - continue; - if (nodeLinkIsHidden(link)) - continue; - - if (flag & REFINE_FORWARD) { - if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done) - node_reroute_inherit_type_recursive(ntree, fromnode, REFINE_FORWARD); - } - if (flag & REFINE_BACKWARD) { - if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done) - node_reroute_inherit_type_recursive(ntree, tonode, REFINE_BACKWARD); - } - } - - /* determine socket type from unambiguous input/output connection if possible */ - if (input->limit == 1 && input->link) { - type = input->link->fromsock->type; - type_idname = nodeStaticSocketType(type, PROP_NONE); - } - else if (output->limit == 1 && output->link) { - type = output->link->tosock->type; - type_idname = nodeStaticSocketType(type, PROP_NONE); - } - - if (input->type != type) { - bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input"); - for (link = ntree->links.first; link; link = link->next) { - if (link->tosock == input) { - link->tosock = ninput; - ninput->link = link; - } - } - nodeRemoveSocket(ntree, node, input); - } - - if (output->type != type) { - bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output"); - for (link = ntree->links.first; link; link = link->next) { - if (link->fromsock == output) { - link->fromsock = noutput; - } - } - nodeRemoveSocket(ntree, node, output); - } - - nodeUpdateInternalLinks(ntree, node); + bNodeSocket *input = node->inputs.first; + bNodeSocket *output = node->outputs.first; + bNodeLink *link; + int type = SOCK_FLOAT; + const char *type_idname = nodeStaticSocketType(type, PROP_NONE); + + /* XXX it would be a little bit more efficient to restrict actual updates + * to rerout nodes connected to an updated node, but there's no reliable flag + * to indicate updated nodes (node->update is not set on linking). + */ + + node->done = 1; + + /* recursive update */ + for (link = ntree->links.first; link; link = link->next) { + bNode *fromnode = link->fromnode; + bNode *tonode = link->tonode; + if (!tonode || !fromnode) + continue; + if (nodeLinkIsHidden(link)) + continue; + + if (flag & REFINE_FORWARD) { + if (tonode == node && fromnode->type == NODE_REROUTE && !fromnode->done) + node_reroute_inherit_type_recursive(ntree, fromnode, REFINE_FORWARD); + } + if (flag & REFINE_BACKWARD) { + if (fromnode == node && tonode->type == NODE_REROUTE && !tonode->done) + node_reroute_inherit_type_recursive(ntree, tonode, REFINE_BACKWARD); + } + } + + /* determine socket type from unambiguous input/output connection if possible */ + if (input->limit == 1 && input->link) { + type = input->link->fromsock->type; + type_idname = nodeStaticSocketType(type, PROP_NONE); + } + else if (output->limit == 1 && output->link) { + type = output->link->tosock->type; + type_idname = nodeStaticSocketType(type, PROP_NONE); + } + + if (input->type != type) { + bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input"); + for (link = ntree->links.first; link; link = link->next) { + if (link->tosock == input) { + link->tosock = ninput; + ninput->link = link; + } + } + nodeRemoveSocket(ntree, node, input); + } + + if (output->type != type) { + bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output"); + for (link = ntree->links.first; link; link = link->next) { + if (link->fromsock == output) { + link->fromsock = noutput; + } + } + nodeRemoveSocket(ntree, node, output); + } + + nodeUpdateInternalLinks(ntree, node); } /* Global update function for Reroute node types. @@ -324,256 +324,255 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node, i */ void ntree_update_reroute_nodes(bNodeTree *ntree) { - bNode *node; + bNode *node; - /* clear tags */ - for (node = ntree->nodes.first; node; node = node->next) - node->done = 0; + /* clear tags */ + for (node = ntree->nodes.first; node; node = node->next) + node->done = 0; - for (node = ntree->nodes.first; node; node = node->next) - if (node->type == NODE_REROUTE && !node->done) - node_reroute_inherit_type_recursive(ntree, node, REFINE_FORWARD | REFINE_BACKWARD); + for (node = ntree->nodes.first; node; node = node->next) + if (node->type == NODE_REROUTE && !node->done) + node_reroute_inherit_type_recursive(ntree, node, REFINE_FORWARD | REFINE_BACKWARD); } static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node) { - bNodeLink *link; - - /* avoid redundant checks, and infinite loops in case of cyclic node links */ - if (node->done) - return false; - node->done = 1; - - /* main test, done before child loop so it catches output nodes themselves as well */ - if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) - return true; - - /* test all connected nodes, first positive find is sufficient to return true */ - for (link = ntree->links.first; link; link = link->next) { - if (link->fromnode == node) { - if (node_is_connected_to_output_recursive(ntree, link->tonode)) - return true; - } - } - return false; + bNodeLink *link; + + /* avoid redundant checks, and infinite loops in case of cyclic node links */ + if (node->done) + return false; + node->done = 1; + + /* main test, done before child loop so it catches output nodes themselves as well */ + if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) + return true; + + /* test all connected nodes, first positive find is sufficient to return true */ + for (link = ntree->links.first; link; link = link->next) { + if (link->fromnode == node) { + if (node_is_connected_to_output_recursive(ntree, link->tonode)) + return true; + } + } + return false; } bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node) { - bNode *tnode; + bNode *tnode; - /* clear flags */ - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) - tnode->done = 0; + /* clear flags */ + for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) + tnode->done = 0; - return node_is_connected_to_output_recursive(ntree, node); + return node_is_connected_to_output_recursive(ntree, node); } void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree) { - bNode *node; + bNode *node; - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id == id) { - node->id = NULL; - } - } + for (node = ntree->nodes.first; node; node = node->next) { + if (node->id == id) { + node->id = NULL; + } + } } /**** GROUP_INPUT / GROUP_OUTPUT ****/ static void node_group_input_init(bNodeTree *ntree, bNode *node) { - node_group_input_verify(ntree, node, (ID *)ntree); + node_group_input_verify(ntree, node, (ID *)ntree); } bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier) { - bNodeSocket *sock; - for (sock = node->outputs.first; sock; sock = sock->next) - if (STREQ(sock->identifier, identifier)) - return sock; - return NULL; + bNodeSocket *sock; + for (sock = node->outputs.first; sock; sock = sock->next) + if (STREQ(sock->identifier, identifier)) + return sock; + return NULL; } void node_group_input_verify(bNodeTree *ntree, bNode *node, ID *id) { - /* check inputs and outputs, and remove or insert them */ - if (id == (ID *)ntree) { - /* 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); - - /* add virtual extension socket */ - nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", ""); - } + /* check inputs and outputs, and remove or insert them */ + if (id == (ID *)ntree) { + /* 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); + + /* add virtual extension socket */ + nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketVirtual", "__extend__", ""); + } } static void node_group_input_update(bNodeTree *ntree, bNode *node) { - bNodeSocket *extsock = node->outputs.last; - bNodeLink *link, *linknext, *exposelink; - /* Adding a tree socket and verifying will remove the extension socket! - * This list caches the existing links from the extension socket - * so they can be recreated after verification. - */ - ListBase tmplinks; - - /* find links from the extension socket and store them */ - BLI_listbase_clear(&tmplinks); - for (link = ntree->links.first; link; link = linknext) { - linknext = link->next; - if (nodeLinkIsHidden(link)) - continue; - - if (link->fromsock == extsock) { - bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link"); - *tlink = *link; - BLI_addtail(&tmplinks, tlink); - - nodeRemLink(ntree, link); - } - } - - /* find valid link to expose */ - exposelink = NULL; - for (link = tmplinks.first; link; link = link->next) { - /* XXX Multiple sockets can be connected to the extension socket at once, - * in that case the arbitrary first link determines name and type. - * This could be improved by choosing the "best" type among all links, - * whatever that means. - */ - if (link->tosock->type != SOCK_CUSTOM) { - exposelink = link; - break; - } - } - - if (exposelink) { - bNodeSocket *gsock, *newsock; - - gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock); - - node_group_input_verify(ntree, node, (ID *)ntree); - newsock = node_group_input_find_socket(node, gsock->identifier); - - /* redirect links from the extension socket */ - for (link = tmplinks.first; link; link = link->next) { - nodeAddLink(ntree, node, newsock, link->tonode, link->tosock); - } - - } - - BLI_freelistN(&tmplinks); + bNodeSocket *extsock = node->outputs.last; + bNodeLink *link, *linknext, *exposelink; + /* Adding a tree socket and verifying will remove the extension socket! + * This list caches the existing links from the extension socket + * so they can be recreated after verification. + */ + ListBase tmplinks; + + /* find links from the extension socket and store them */ + BLI_listbase_clear(&tmplinks); + for (link = ntree->links.first; link; link = linknext) { + linknext = link->next; + if (nodeLinkIsHidden(link)) + continue; + + if (link->fromsock == extsock) { + bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link"); + *tlink = *link; + BLI_addtail(&tmplinks, tlink); + + nodeRemLink(ntree, link); + } + } + + /* find valid link to expose */ + exposelink = NULL; + for (link = tmplinks.first; link; link = link->next) { + /* XXX Multiple sockets can be connected to the extension socket at once, + * in that case the arbitrary first link determines name and type. + * This could be improved by choosing the "best" type among all links, + * whatever that means. + */ + if (link->tosock->type != SOCK_CUSTOM) { + exposelink = link; + break; + } + } + + if (exposelink) { + bNodeSocket *gsock, *newsock; + + gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock); + + node_group_input_verify(ntree, node, (ID *)ntree); + newsock = node_group_input_find_socket(node, gsock->identifier); + + /* redirect links from the extension socket */ + for (link = tmplinks.first; link; link = link->next) { + nodeAddLink(ntree, node, newsock, link->tonode, link->tosock); + } + } + + BLI_freelistN(&tmplinks); } void register_node_type_group_input(void) { - /* used for all tree types, needs dynamic allocation */ - bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type"); + /* used for all tree types, needs dynamic allocation */ + bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type"); - node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE, 0); - node_type_size(ntype, 140, 80, 400); - node_type_init(ntype, node_group_input_init); - node_type_update(ntype, node_group_input_update, node_group_input_verify); + node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE, 0); + node_type_size(ntype, 140, 80, 400); + node_type_init(ntype, node_group_input_init); + node_type_update(ntype, node_group_input_update, node_group_input_verify); - ntype->needs_free = 1; - nodeRegisterType(ntype); + ntype->needs_free = 1; + nodeRegisterType(ntype); } static void node_group_output_init(bNodeTree *ntree, bNode *node) { - node_group_output_verify(ntree, node, (ID *)ntree); + node_group_output_verify(ntree, node, (ID *)ntree); } bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier) { - bNodeSocket *sock; - for (sock = node->inputs.first; sock; sock = sock->next) - if (STREQ(sock->identifier, identifier)) - return sock; - return NULL; + bNodeSocket *sock; + for (sock = node->inputs.first; sock; sock = sock->next) + if (STREQ(sock->identifier, identifier)) + return sock; + return NULL; } void node_group_output_verify(bNodeTree *ntree, bNode *node, ID *id) { - /* check inputs and outputs, and remove or insert them */ - if (id == (ID *)ntree) { - /* 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); - - /* add virtual extension socket */ - nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", ""); - } + /* check inputs and outputs, and remove or insert them */ + if (id == (ID *)ntree) { + /* 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); + + /* add virtual extension socket */ + nodeAddSocket(ntree, node, SOCK_IN, "NodeSocketVirtual", "__extend__", ""); + } } static void node_group_output_update(bNodeTree *ntree, bNode *node) { - bNodeSocket *extsock = node->inputs.last; - bNodeLink *link, *linknext, *exposelink; - /* Adding a tree socket and verifying will remove the extension socket! - * This list caches the existing links to the extension socket - * so they can be recreated after verification. - */ - ListBase tmplinks; - - /* find links to the extension socket and store them */ - BLI_listbase_clear(&tmplinks); - for (link = ntree->links.first; link; link = linknext) { - linknext = link->next; - if (nodeLinkIsHidden(link)) - continue; - - if (link->tosock == extsock) { - bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link"); - *tlink = *link; - BLI_addtail(&tmplinks, tlink); - - nodeRemLink(ntree, link); - } - } - - /* find valid link to expose */ - exposelink = NULL; - for (link = tmplinks.first; link; link = link->next) { - /* XXX Multiple sockets can be connected to the extension socket at once, - * in that case the arbitrary first link determines name and type. - * This could be improved by choosing the "best" type among all links, - * whatever that means. - */ - if (link->fromsock->type != SOCK_CUSTOM) { - exposelink = link; - break; - } - } - - if (exposelink) { - bNodeSocket *gsock, *newsock; - - /* XXX what if connecting virtual to virtual socket?? */ - gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock); - - node_group_output_verify(ntree, node, (ID *)ntree); - newsock = node_group_output_find_socket(node, gsock->identifier); - - /* redirect links to the extension socket */ - for (link = tmplinks.first; link; link = link->next) { - nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock); - } - } - - BLI_freelistN(&tmplinks); + bNodeSocket *extsock = node->inputs.last; + bNodeLink *link, *linknext, *exposelink; + /* Adding a tree socket and verifying will remove the extension socket! + * This list caches the existing links to the extension socket + * so they can be recreated after verification. + */ + ListBase tmplinks; + + /* find links to the extension socket and store them */ + BLI_listbase_clear(&tmplinks); + for (link = ntree->links.first; link; link = linknext) { + linknext = link->next; + if (nodeLinkIsHidden(link)) + continue; + + if (link->tosock == extsock) { + bNodeLink *tlink = MEM_callocN(sizeof(bNodeLink), "temporary link"); + *tlink = *link; + BLI_addtail(&tmplinks, tlink); + + nodeRemLink(ntree, link); + } + } + + /* find valid link to expose */ + exposelink = NULL; + for (link = tmplinks.first; link; link = link->next) { + /* XXX Multiple sockets can be connected to the extension socket at once, + * in that case the arbitrary first link determines name and type. + * This could be improved by choosing the "best" type among all links, + * whatever that means. + */ + if (link->fromsock->type != SOCK_CUSTOM) { + exposelink = link; + break; + } + } + + if (exposelink) { + bNodeSocket *gsock, *newsock; + + /* XXX what if connecting virtual to virtual socket?? */ + gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock); + + node_group_output_verify(ntree, node, (ID *)ntree); + newsock = node_group_output_find_socket(node, gsock->identifier); + + /* redirect links to the extension socket */ + for (link = tmplinks.first; link; link = link->next) { + nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock); + } + } + + BLI_freelistN(&tmplinks); } void register_node_type_group_output(void) { - /* used for all tree types, needs dynamic allocation */ - bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type"); + /* used for all tree types, needs dynamic allocation */ + bNodeType *ntype = MEM_callocN(sizeof(bNodeType), "node type"); - node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE, 0); - node_type_size(ntype, 140, 80, 400); - node_type_init(ntype, node_group_output_init); - node_type_update(ntype, node_group_output_update, node_group_output_verify); + node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE, 0); + node_type_size(ntype, 140, 80, 400); + node_type_init(ntype, node_group_output_init); + node_type_update(ntype, node_group_output_update, node_group_output_verify); - ntype->needs_free = 1; - nodeRegisterType(ntype); + ntype->needs_free = 1; + nodeRegisterType(ntype); } diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index 14342d31204..c3314ae3c28 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -21,7 +21,6 @@ * \ingroup nodes */ - #ifndef __NODE_COMMON_H__ #define __NODE_COMMON_H__ diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c index 97d93ee0fa5..ed3dbf4515b 100644 --- a/source/blender/nodes/intern/node_exec.c +++ b/source/blender/nodes/intern/node_exec.c @@ -21,7 +21,6 @@ * \ingroup nodes */ - #include "DNA_node_types.h" #include "BLI_listbase.h" @@ -35,275 +34,281 @@ #include "node_exec.h" #include "node_util.h" - /* supported socket types in old nodes */ int node_exec_socket_use_stack(bNodeSocket *sock) { - /* NOTE: INT supported as FLOAT. Only for EEVEE. */ - return ELEM(sock->type, SOCK_INT, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER); + /* NOTE: INT supported as FLOAT. Only for EEVEE. */ + return ELEM(sock->type, SOCK_INT, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER); } /* for a given socket, find the actual stack entry */ bNodeStack *node_get_socket_stack(bNodeStack *stack, bNodeSocket *sock) { - if (stack && sock && sock->stack_index >= 0) - return stack + sock->stack_index; - return NULL; + if (stack && sock && sock->stack_index >= 0) + return stack + sock->stack_index; + return NULL; } void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock; - - /* build pointer stack */ - if (in) { - for (sock = node->inputs.first; sock; sock = sock->next) { - *(in++) = node_get_socket_stack(stack, sock); - } - } - - if (out) { - for (sock = node->outputs.first; sock; sock = sock->next) { - *(out++) = node_get_socket_stack(stack, sock); - } - } + bNodeSocket *sock; + + /* build pointer stack */ + if (in) { + for (sock = node->inputs.first; sock; sock = sock->next) { + *(in++) = node_get_socket_stack(stack, sock); + } + } + + if (out) { + for (sock = node->outputs.first; sock; sock = sock->next) { + *(out++) = node_get_socket_stack(stack, sock); + } + } } static void node_init_input_index(bNodeSocket *sock, int *index) { - /* Only consider existing link if from socket is valid! */ - if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) { - sock->stack_index = sock->link->fromsock->stack_index; - } - else { - if (node_exec_socket_use_stack(sock)) - sock->stack_index = (*index)++; - else - sock->stack_index = -1; - } + /* Only consider existing link if from socket is valid! */ + if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) { + sock->stack_index = sock->link->fromsock->stack_index; + } + else { + if (node_exec_socket_use_stack(sock)) + sock->stack_index = (*index)++; + else + sock->stack_index = -1; + } } static void node_init_output_index(bNodeSocket *sock, int *index, ListBase *internal_links) { - if (internal_links) { - bNodeLink *link; - /* copy the stack index from internally connected input to skip the node */ - for (link = internal_links->first; link; link = link->next) { - if (link->tosock == sock) { - sock->stack_index = link->fromsock->stack_index; - /* set the link pointer to indicate that this socket - * should not overwrite the stack value! - */ - sock->link = link; - break; - } - } - /* if not internally connected, assign a new stack index anyway to avoid bad stack access */ - if (!link) { - if (node_exec_socket_use_stack(sock)) - sock->stack_index = (*index)++; - else - sock->stack_index = -1; - } - } - else { - if (node_exec_socket_use_stack(sock)) - sock->stack_index = (*index)++; - else - sock->stack_index = -1; - } + if (internal_links) { + bNodeLink *link; + /* copy the stack index from internally connected input to skip the node */ + for (link = internal_links->first; link; link = link->next) { + if (link->tosock == sock) { + sock->stack_index = link->fromsock->stack_index; + /* set the link pointer to indicate that this socket + * should not overwrite the stack value! + */ + sock->link = link; + break; + } + } + /* if not internally connected, assign a new stack index anyway to avoid bad stack access */ + if (!link) { + if (node_exec_socket_use_stack(sock)) + sock->stack_index = (*index)++; + else + sock->stack_index = -1; + } + } + else { + if (node_exec_socket_use_stack(sock)) + sock->stack_index = (*index)++; + else + sock->stack_index = -1; + } } /* basic preparation of socket stacks */ -static struct bNodeStack *setup_stack(bNodeStack *stack, bNodeTree *ntree, bNode *node, bNodeSocket *sock) +static struct bNodeStack *setup_stack(bNodeStack *stack, + bNodeTree *ntree, + bNode *node, + bNodeSocket *sock) { - bNodeStack *ns = node_get_socket_stack(stack, sock); - if (!ns) - return NULL; - - /* don't mess with remote socket stacks, these are initialized by other nodes! */ - if (sock->link) - return ns; - - ns->sockettype = sock->type; - - switch (sock->type) { - case SOCK_FLOAT: - ns->vec[0] = node_socket_get_float(ntree, node, sock); - break; - case SOCK_VECTOR: - node_socket_get_vector(ntree, node, sock, ns->vec); - break; - case SOCK_RGBA: - node_socket_get_color(ntree, node, sock, ns->vec); - break; - } - - return ns; + bNodeStack *ns = node_get_socket_stack(stack, sock); + if (!ns) + return NULL; + + /* don't mess with remote socket stacks, these are initialized by other nodes! */ + if (sock->link) + return ns; + + ns->sockettype = sock->type; + + switch (sock->type) { + case SOCK_FLOAT: + ns->vec[0] = node_socket_get_float(ntree, node, sock); + break; + case SOCK_VECTOR: + node_socket_get_vector(ntree, node, sock, ns->vec); + break; + case SOCK_RGBA: + node_socket_get_color(ntree, node, sock, ns->vec); + break; + } + + return ns; } -bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key) +bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, + bNodeTree *ntree, + bNodeInstanceKey parent_key) { - bNodeTreeExec *exec; - bNode *node; - bNodeExec *nodeexec; - bNodeInstanceKey nodekey; - bNodeSocket *sock; - bNodeStack *ns; - int index; - bNode **nodelist; - int totnodes, n; - /* XXX texnodes have threading issues with muting, have to disable it there ... */ - - /* ensure all sock->link pointers and node levels are correct */ - /* Using global main here is likely totally wrong, not sure what to do about that one though... - * We cannot even check ntree is in global main, since most of the time it won't be (thanks to ntree design)!!! */ - ntreeUpdateTree(G.main, ntree); - - /* get a dependency-sorted list of nodes */ - ntreeGetDependencyList(ntree, &nodelist, &totnodes); - - /* XXX could let callbacks do this for specialized data */ - exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data"); - /* backpointer to node tree */ - exec->nodetree = ntree; - - /* set stack indices */ - index = 0; - for (n = 0; n < totnodes; ++n) { - node = nodelist[n]; - - node->stack_index = index; - - /* init node socket stack indexes */ - for (sock = node->inputs.first; sock; sock = sock->next) - node_init_input_index(sock, &index); - - if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) { - for (sock = node->outputs.first; sock; sock = sock->next) - node_init_output_index(sock, &index, &node->internal_links); - } - else { - for (sock = node->outputs.first; sock; sock = sock->next) - node_init_output_index(sock, &index, NULL); - } - } - - /* allocated exec data pointers for nodes */ - exec->totnodes = totnodes; - exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data"); - /* allocate data pointer for node stack */ - exec->stacksize = index; - exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack"); - - /* all non-const results are considered inputs */ - for (n = 0; n < exec->stacksize; ++n) - exec->stack[n].hasinput = 1; - - /* prepare all nodes for execution */ - for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) { - node = nodeexec->node = nodelist[n]; - nodeexec->freeexecfunc = node->typeinfo->freeexecfunc; - - /* tag inputs */ - for (sock = node->inputs.first; sock; sock = sock->next) { - /* disable the node if an input link is invalid */ - if (sock->link && !(sock->link->flag & NODE_LINK_VALID)) - node->need_exec = 0; - - ns = setup_stack(exec->stack, ntree, node, sock); - if (ns) - ns->hasoutput = 1; - } - - /* tag all outputs */ - for (sock = node->outputs.first; sock; sock = sock->next) { - /* ns = */ setup_stack(exec->stack, ntree, node, sock); - } - - nodekey = BKE_node_instance_key(parent_key, ntree, node); - nodeexec->data.preview = context->previews ? BKE_node_instance_hash_lookup(context->previews, nodekey) : NULL; - if (node->typeinfo->initexecfunc) - nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey); - } - - if (nodelist) - MEM_freeN(nodelist); - - return exec; + bNodeTreeExec *exec; + bNode *node; + bNodeExec *nodeexec; + bNodeInstanceKey nodekey; + bNodeSocket *sock; + bNodeStack *ns; + int index; + bNode **nodelist; + int totnodes, n; + /* XXX texnodes have threading issues with muting, have to disable it there ... */ + + /* ensure all sock->link pointers and node levels are correct */ + /* Using global main here is likely totally wrong, not sure what to do about that one though... + * We cannot even check ntree is in global main, since most of the time it won't be (thanks to ntree design)!!! */ + ntreeUpdateTree(G.main, ntree); + + /* get a dependency-sorted list of nodes */ + ntreeGetDependencyList(ntree, &nodelist, &totnodes); + + /* XXX could let callbacks do this for specialized data */ + exec = MEM_callocN(sizeof(bNodeTreeExec), "node tree execution data"); + /* backpointer to node tree */ + exec->nodetree = ntree; + + /* set stack indices */ + index = 0; + for (n = 0; n < totnodes; ++n) { + node = nodelist[n]; + + node->stack_index = index; + + /* init node socket stack indexes */ + for (sock = node->inputs.first; sock; sock = sock->next) + node_init_input_index(sock, &index); + + if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) { + for (sock = node->outputs.first; sock; sock = sock->next) + node_init_output_index(sock, &index, &node->internal_links); + } + else { + for (sock = node->outputs.first; sock; sock = sock->next) + node_init_output_index(sock, &index, NULL); + } + } + + /* allocated exec data pointers for nodes */ + exec->totnodes = totnodes; + exec->nodeexec = MEM_callocN(exec->totnodes * sizeof(bNodeExec), "node execution data"); + /* allocate data pointer for node stack */ + exec->stacksize = index; + exec->stack = MEM_callocN(exec->stacksize * sizeof(bNodeStack), "bNodeStack"); + + /* all non-const results are considered inputs */ + for (n = 0; n < exec->stacksize; ++n) + exec->stack[n].hasinput = 1; + + /* prepare all nodes for execution */ + for (n = 0, nodeexec = exec->nodeexec; n < totnodes; ++n, ++nodeexec) { + node = nodeexec->node = nodelist[n]; + nodeexec->freeexecfunc = node->typeinfo->freeexecfunc; + + /* tag inputs */ + for (sock = node->inputs.first; sock; sock = sock->next) { + /* disable the node if an input link is invalid */ + if (sock->link && !(sock->link->flag & NODE_LINK_VALID)) + node->need_exec = 0; + + ns = setup_stack(exec->stack, ntree, node, sock); + if (ns) + ns->hasoutput = 1; + } + + /* tag all outputs */ + for (sock = node->outputs.first; sock; sock = sock->next) { + /* ns = */ setup_stack(exec->stack, ntree, node, sock); + } + + nodekey = BKE_node_instance_key(parent_key, ntree, node); + nodeexec->data.preview = context->previews ? + BKE_node_instance_hash_lookup(context->previews, nodekey) : + NULL; + if (node->typeinfo->initexecfunc) + nodeexec->data.data = node->typeinfo->initexecfunc(context, node, nodekey); + } + + if (nodelist) + MEM_freeN(nodelist); + + return exec; } void ntree_exec_end(bNodeTreeExec *exec) { - bNodeExec *nodeexec; - int n; + bNodeExec *nodeexec; + int n; - if (exec->stack) - MEM_freeN(exec->stack); + if (exec->stack) + MEM_freeN(exec->stack); - for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - if (nodeexec->freeexecfunc) - nodeexec->freeexecfunc(nodeexec->data.data); - } + for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + if (nodeexec->freeexecfunc) + nodeexec->freeexecfunc(nodeexec->data.data); + } - if (exec->nodeexec) - MEM_freeN(exec->nodeexec); + if (exec->nodeexec) + MEM_freeN(exec->nodeexec); - MEM_freeN(exec); + MEM_freeN(exec); } /**** Material/Texture trees ****/ bNodeThreadStack *ntreeGetThreadStack(bNodeTreeExec *exec, int thread) { - ListBase *lb = &exec->threadstack[thread]; - bNodeThreadStack *nts; - - for (nts = lb->first; nts; nts = nts->next) { - if (!nts->used) { - nts->used = true; - break; - } - } - - if (!nts) { - nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack"); - nts->stack = MEM_dupallocN(exec->stack); - nts->used = true; - BLI_addtail(lb, nts); - } - - return nts; + ListBase *lb = &exec->threadstack[thread]; + bNodeThreadStack *nts; + + for (nts = lb->first; nts; nts = nts->next) { + if (!nts->used) { + nts->used = true; + break; + } + } + + if (!nts) { + nts = MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack"); + nts->stack = MEM_dupallocN(exec->stack); + nts->used = true; + BLI_addtail(lb, nts); + } + + return nts; } void ntreeReleaseThreadStack(bNodeThreadStack *nts) { - nts->used = 0; + nts->used = 0; } bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *callerdata, int thread) { - bNodeStack *nsin[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */ - bNodeStack *nsout[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */ - bNodeExec *nodeexec; - bNode *node; - int n; - - /* nodes are presorted, so exec is in order of list */ - - for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { - node = nodeexec->node; - if (node->need_exec) { - node_get_stack(node, nts->stack, nsin, nsout); - /* Handle muted nodes... - * If the mute func is not set, assume the node should never be muted, - * and hence execute it! - */ - if (node->typeinfo->execfunc && !(node->flag & NODE_MUTED)) - node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout); - } - } - - /* signal to that all went OK, for render */ - return true; + bNodeStack *nsin[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET] = {NULL}; /* arbitrary... watch this */ + bNodeExec *nodeexec; + bNode *node; + int n; + + /* nodes are presorted, so exec is in order of list */ + + for (n = 0, nodeexec = exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { + node = nodeexec->node; + if (node->need_exec) { + node_get_stack(node, nts->stack, nsin, nsout); + /* Handle muted nodes... + * If the mute func is not set, assume the node should never be muted, + * and hence execute it! + */ + if (node->typeinfo->execfunc && !(node->flag & NODE_MUTED)) + node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout); + } + } + + /* signal to that all went OK, for render */ + return true; } diff --git a/source/blender/nodes/intern/node_exec.h b/source/blender/nodes/intern/node_exec.h index 145bee149d1..336a8f26ec3 100644 --- a/source/blender/nodes/intern/node_exec.h +++ b/source/blender/nodes/intern/node_exec.h @@ -21,7 +21,6 @@ * \ingroup nodes */ - #ifndef __NODE_EXEC_H__ #define __NODE_EXEC_H__ @@ -41,48 +40,61 @@ struct bNodeTree; /* Node execution data */ typedef struct bNodeExec { - struct bNode *node; /* backpointer to node */ - bNodeExecData data; + struct bNode *node; /* backpointer to node */ + bNodeExecData data; - NodeFreeExecFunction freeexecfunc; /* free function, stored in exec itself to avoid dangling node pointer access */ + NodeFreeExecFunction + freeexecfunc; /* free function, stored in exec itself to avoid dangling node pointer access */ } bNodeExec; /* Execution Data for each instance of node tree execution */ typedef struct bNodeTreeExec { - struct bNodeTree *nodetree; /* backpointer to node tree */ + struct bNodeTree *nodetree; /* backpointer to node tree */ - int totnodes; /* total node count */ - struct bNodeExec *nodeexec; /* per-node execution data */ + int totnodes; /* total node count */ + struct bNodeExec *nodeexec; /* per-node execution data */ - int stacksize; - struct bNodeStack *stack; /* socket data stack */ - /* only used by material and texture trees to keep one stack for each thread */ - ListBase *threadstack; /* one instance of the stack for each thread */ + int stacksize; + struct bNodeStack *stack; /* socket data stack */ + /* only used by material and texture trees to keep one stack for each thread */ + ListBase *threadstack; /* one instance of the stack for each thread */ } bNodeTreeExec; /* stores one stack copy for each thread (material and texture trees) */ typedef struct bNodeThreadStack { - struct bNodeThreadStack *next, *prev; - struct bNodeStack *stack; - bool used; + struct bNodeThreadStack *next, *prev; + struct bNodeStack *stack; + bool used; } bNodeThreadStack; int node_exec_socket_use_stack(struct bNodeSocket *sock); struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock); -void node_get_stack(struct bNode *node, struct bNodeStack *stack, struct bNodeStack **in, struct bNodeStack **out); - -struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key); +void node_get_stack(struct bNode *node, + struct bNodeStack *stack, + struct bNodeStack **in, + struct bNodeStack **out); + +struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, + struct bNodeTree *ntree, + bNodeInstanceKey parent_key); void ntree_exec_end(struct bNodeTreeExec *exec); struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread); void ntreeReleaseThreadStack(struct bNodeThreadStack *nts); -bool ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread); - -struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key); +bool ntreeExecThreadNodes(struct bNodeTreeExec *exec, + struct bNodeThreadStack *nts, + void *callerdata, + int thread); + +struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, + struct bNodeTree *ntree, + bNodeInstanceKey parent_key); void ntreeShaderEndExecTree_internal(struct bNodeTreeExec *exec); -struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key); +struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, + struct bNodeTree *ntree, + bNodeInstanceKey parent_key); void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec); #endif diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 351e579d924..9fe6e0bcecb 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -41,439 +41,443 @@ struct Main; -struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp, int in_out) +struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocketTemplate *stemp, + int in_out) { - bNodeSocket *sock = nodeAddStaticSocket(ntree, node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name); - - sock->flag |= stemp->flag; - - /* initialize default_value */ - switch (stemp->type) { - case SOCK_FLOAT: - { - bNodeSocketValueFloat *dval = sock->default_value; - dval->value = stemp->val1; - dval->min = stemp->min; - dval->max = stemp->max; - break; - } - case SOCK_INT: - { - bNodeSocketValueInt *dval = sock->default_value; - dval->value = (int)stemp->val1; - dval->min = (int)stemp->min; - dval->max = (int)stemp->max; - break; - } - case SOCK_BOOLEAN: - { - bNodeSocketValueBoolean *dval = sock->default_value; - dval->value = (int)stemp->val1; - break; - } - case SOCK_VECTOR: - { - bNodeSocketValueVector *dval = sock->default_value; - dval->value[0] = stemp->val1; - dval->value[1] = stemp->val2; - dval->value[2] = stemp->val3; - dval->min = stemp->min; - dval->max = stemp->max; - break; - } - case SOCK_RGBA: - { - bNodeSocketValueRGBA *dval = sock->default_value; - dval->value[0] = stemp->val1; - dval->value[1] = stemp->val2; - dval->value[2] = stemp->val3; - dval->value[3] = stemp->val4; - break; - } - } - - return sock; + bNodeSocket *sock = nodeAddStaticSocket( + ntree, node, in_out, stemp->type, stemp->subtype, stemp->identifier, stemp->name); + + sock->flag |= stemp->flag; + + /* initialize default_value */ + switch (stemp->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *dval = sock->default_value; + dval->value = stemp->val1; + dval->min = stemp->min; + dval->max = stemp->max; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *dval = sock->default_value; + dval->value = (int)stemp->val1; + dval->min = (int)stemp->min; + dval->max = (int)stemp->max; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *dval = sock->default_value; + dval->value = (int)stemp->val1; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *dval = sock->default_value; + dval->value[0] = stemp->val1; + dval->value[1] = stemp->val2; + dval->value[2] = stemp->val3; + dval->min = stemp->min; + dval->max = stemp->max; + break; + } + case SOCK_RGBA: { + bNodeSocketValueRGBA *dval = sock->default_value; + dval->value[0] = stemp->val1; + dval->value[1] = stemp->val2; + dval->value[2] = stemp->val3; + dval->value[3] = stemp->val4; + break; + } + } + + return sock; } -static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp) +static bNodeSocket *verify_socket_template( + bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp) { - bNodeSocket *sock; - - for (sock = socklist->first; sock; sock = sock->next) { - if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR)) - break; - } - if (sock) { - if (sock->type != stemp->type) { - nodeModifySocketType(ntree, node, sock, stemp->type, stemp->subtype); - } - sock->limit = (stemp->limit == 0 ? (in_out == SOCK_IN ? 1 : 0xFFF) : stemp->limit); - sock->flag |= stemp->flag; - } - else { - /* no socket for this template found, make a new one */ - sock = node_add_socket_from_template(ntree, node, stemp, in_out); - } - - /* remove the new socket from the node socket list first, - * will be added back after verification. */ - BLI_remlink(socklist, sock); - - return sock; + bNodeSocket *sock; + + for (sock = socklist->first; sock; sock = sock->next) { + if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR)) + break; + } + if (sock) { + if (sock->type != stemp->type) { + nodeModifySocketType(ntree, node, sock, stemp->type, stemp->subtype); + } + sock->limit = (stemp->limit == 0 ? (in_out == SOCK_IN ? 1 : 0xFFF) : stemp->limit); + sock->flag |= stemp->flag; + } + else { + /* no socket for this template found, make a new one */ + sock = node_add_socket_from_template(ntree, node, stemp, in_out); + } + + /* remove the new socket from the node socket list first, + * will be added back after verification. */ + BLI_remlink(socklist, sock); + + return sock; } -static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first) +static void verify_socket_template_list(bNodeTree *ntree, + bNode *node, + int in_out, + ListBase *socklist, + bNodeSocketTemplate *stemp_first) { - bNodeSocket *sock, *nextsock; - bNodeSocketTemplate *stemp; - - /* no inputs anymore? */ - if (stemp_first == NULL) { - for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) { - nextsock = sock->next; - nodeRemoveSocket(ntree, node, sock); - } - } - else { - /* step by step compare */ - stemp = stemp_first; - while (stemp->type != -1) { - stemp->sock = verify_socket_template(ntree, node, in_out, socklist, stemp); - stemp++; - } - /* leftovers are removed */ - for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) { - nextsock = sock->next; - nodeRemoveSocket(ntree, node, sock); - } - - /* and we put back the verified sockets */ - stemp = stemp_first; - if (socklist->first) { - /* some dynamic sockets left, store the list start - * so we can add static sockets infront of it. - */ - sock = socklist->first; - while (stemp->type != -1) { - /* put static sockets infront of dynamic */ - BLI_insertlinkbefore(socklist, sock, stemp->sock); - stemp++; - } - } - else { - while (stemp->type != -1) { - BLI_addtail(socklist, stemp->sock); - stemp++; - } - } - } + bNodeSocket *sock, *nextsock; + bNodeSocketTemplate *stemp; + + /* no inputs anymore? */ + if (stemp_first == NULL) { + for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) { + nextsock = sock->next; + nodeRemoveSocket(ntree, node, sock); + } + } + else { + /* step by step compare */ + stemp = stemp_first; + while (stemp->type != -1) { + stemp->sock = verify_socket_template(ntree, node, in_out, socklist, stemp); + stemp++; + } + /* leftovers are removed */ + for (sock = (bNodeSocket *)socklist->first; sock; sock = nextsock) { + nextsock = sock->next; + nodeRemoveSocket(ntree, node, sock); + } + + /* and we put back the verified sockets */ + stemp = stemp_first; + if (socklist->first) { + /* some dynamic sockets left, store the list start + * so we can add static sockets infront of it. + */ + sock = socklist->first; + while (stemp->type != -1) { + /* put static sockets infront of dynamic */ + BLI_insertlinkbefore(socklist, sock, stemp->sock); + stemp++; + } + } + else { + while (stemp->type != -1) { + BLI_addtail(socklist, stemp->sock); + stemp++; + } + } + } } void node_verify_socket_templates(bNodeTree *ntree, bNode *node) { - bNodeType *ntype = node->typeinfo; - /* Don't try to match socket lists when there are no templates. - * This prevents dynamically generated sockets to be removed, like for - * group, image or render layer nodes. We have an explicit check for the - * render layer node since it still has fixed sockets too. - */ - if (ntype) { - if (ntype->inputs && ntype->inputs[0].type >= 0) - verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs); - if (ntype->outputs && ntype->outputs[0].type >= 0 && node->type != CMP_NODE_R_LAYERS) - verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs); - } + bNodeType *ntype = node->typeinfo; + /* Don't try to match socket lists when there are no templates. + * This prevents dynamically generated sockets to be removed, like for + * group, image or render layer nodes. We have an explicit check for the + * render layer node since it still has fixed sockets too. + */ + if (ntype) { + if (ntype->inputs && ntype->inputs[0].type >= 0) + verify_socket_template_list(ntree, node, SOCK_IN, &node->inputs, ntype->inputs); + if (ntype->outputs && ntype->outputs[0].type >= 0 && node->type != CMP_NODE_R_LAYERS) + verify_socket_template_list(ntree, node, SOCK_OUT, &node->outputs, ntype->outputs); + } } - void node_socket_init_default_value(bNodeSocket *sock) { - int type = sock->typeinfo->type; - int subtype = sock->typeinfo->subtype; - - if (sock->default_value) - return; /* already initialized */ - - switch (type) { - case SOCK_FLOAT: - { - bNodeSocketValueFloat *dval = MEM_callocN(sizeof(bNodeSocketValueFloat), "node socket value float"); - dval->subtype = subtype; - dval->value = 0.0f; - dval->min = -FLT_MAX; - dval->max = FLT_MAX; - - sock->default_value = dval; - break; - } - case SOCK_INT: - { - bNodeSocketValueInt *dval = MEM_callocN(sizeof(bNodeSocketValueInt), "node socket value int"); - dval->subtype = subtype; - dval->value = 0; - dval->min = INT_MIN; - dval->max = INT_MAX; - - sock->default_value = dval; - break; - } - case SOCK_BOOLEAN: - { - bNodeSocketValueBoolean *dval = MEM_callocN(sizeof(bNodeSocketValueBoolean), "node socket value bool"); - dval->value = false; - - sock->default_value = dval; - break; - } - case SOCK_VECTOR: - { - static float default_value[] = { 0.0f, 0.0f, 0.0f }; - bNodeSocketValueVector *dval = MEM_callocN(sizeof(bNodeSocketValueVector), "node socket value vector"); - dval->subtype = subtype; - copy_v3_v3(dval->value, default_value); - dval->min = -FLT_MAX; - dval->max = FLT_MAX; - - sock->default_value = dval; - break; - } - case SOCK_RGBA: - { - static float default_value[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - bNodeSocketValueRGBA *dval = MEM_callocN(sizeof(bNodeSocketValueRGBA), "node socket value color"); - copy_v4_v4(dval->value, default_value); - - sock->default_value = dval; - break; - } - case SOCK_STRING: - { - bNodeSocketValueString *dval = MEM_callocN(sizeof(bNodeSocketValueString), "node socket value string"); - dval->subtype = subtype; - dval->value[0] = '\0'; - - sock->default_value = dval; - break; - } - } + int type = sock->typeinfo->type; + int subtype = sock->typeinfo->subtype; + + if (sock->default_value) + return; /* already initialized */ + + switch (type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *dval = MEM_callocN(sizeof(bNodeSocketValueFloat), + "node socket value float"); + dval->subtype = subtype; + dval->value = 0.0f; + dval->min = -FLT_MAX; + dval->max = FLT_MAX; + + sock->default_value = dval; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *dval = MEM_callocN(sizeof(bNodeSocketValueInt), + "node socket value int"); + dval->subtype = subtype; + dval->value = 0; + dval->min = INT_MIN; + dval->max = INT_MAX; + + sock->default_value = dval; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *dval = MEM_callocN(sizeof(bNodeSocketValueBoolean), + "node socket value bool"); + dval->value = false; + + sock->default_value = dval; + break; + } + case SOCK_VECTOR: { + static float default_value[] = {0.0f, 0.0f, 0.0f}; + bNodeSocketValueVector *dval = MEM_callocN(sizeof(bNodeSocketValueVector), + "node socket value vector"); + dval->subtype = subtype; + copy_v3_v3(dval->value, default_value); + dval->min = -FLT_MAX; + dval->max = FLT_MAX; + + sock->default_value = dval; + break; + } + case SOCK_RGBA: { + static float default_value[] = {0.0f, 0.0f, 0.0f, 1.0f}; + bNodeSocketValueRGBA *dval = MEM_callocN(sizeof(bNodeSocketValueRGBA), + "node socket value color"); + copy_v4_v4(dval->value, default_value); + + sock->default_value = dval; + break; + } + case SOCK_STRING: { + bNodeSocketValueString *dval = MEM_callocN(sizeof(bNodeSocketValueString), + "node socket value string"); + dval->subtype = subtype; + dval->value[0] = '\0'; + + sock->default_value = dval; + break; + } + } } void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from) { - /* sanity check */ - if (to->type != from->type) - return; - - /* make sure both exist */ - if (!from->default_value) - return; - node_socket_init_default_value(to); - - switch (from->typeinfo->type) { - case SOCK_FLOAT: - { - bNodeSocketValueFloat *toval = to->default_value; - bNodeSocketValueFloat *fromval = from->default_value; - *toval = *fromval; - break; - } - case SOCK_INT: - { - bNodeSocketValueInt *toval = to->default_value; - bNodeSocketValueInt *fromval = from->default_value; - *toval = *fromval; - break; - } - case SOCK_BOOLEAN: - { - bNodeSocketValueBoolean *toval = to->default_value; - bNodeSocketValueBoolean *fromval = from->default_value; - *toval = *fromval; - break; - } - case SOCK_VECTOR: - { - bNodeSocketValueVector *toval = to->default_value; - bNodeSocketValueVector *fromval = from->default_value; - *toval = *fromval; - break; - } - case SOCK_RGBA: - { - bNodeSocketValueRGBA *toval = to->default_value; - bNodeSocketValueRGBA *fromval = from->default_value; - *toval = *fromval; - break; - } - case SOCK_STRING: - { - bNodeSocketValueString *toval = to->default_value; - bNodeSocketValueString *fromval = from->default_value; - *toval = *fromval; - break; - } - } - - to->flag |= (from->flag & SOCK_HIDE_VALUE); + /* sanity check */ + if (to->type != from->type) + return; + + /* make sure both exist */ + if (!from->default_value) + return; + node_socket_init_default_value(to); + + switch (from->typeinfo->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *toval = to->default_value; + bNodeSocketValueFloat *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = to->default_value; + bNodeSocketValueInt *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *toval = to->default_value; + bNodeSocketValueBoolean *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = to->default_value; + bNodeSocketValueVector *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_RGBA: { + bNodeSocketValueRGBA *toval = to->default_value; + bNodeSocketValueRGBA *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_STRING: { + bNodeSocketValueString *toval = to->default_value; + bNodeSocketValueString *fromval = from->default_value; + *toval = *fromval; + break; + } + } + + to->flag |= (from->flag & SOCK_HIDE_VALUE); } -static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock, const char *UNUSED(data_path)) +static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), + bNodeSocket *stemp, + bNode *UNUSED(node), + bNodeSocket *sock, + const char *UNUSED(data_path)) { - /* initialize the type value */ - sock->type = sock->typeinfo->type; - - /* XXX socket interface 'type' value is not used really, - * but has to match or the copy function will bail out - */ - stemp->type = stemp->typeinfo->type; - /* copy default_value settings */ - node_socket_copy_default_value(sock, stemp); + /* initialize the type value */ + sock->type = sock->typeinfo->type; + + /* XXX socket interface 'type' value is not used really, + * but has to match or the copy function will bail out + */ + stemp->type = stemp->typeinfo->type; + /* copy default_value settings */ + node_socket_copy_default_value(sock, stemp); } /* copies settings that are not changed for each socket instance */ -static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock, const char *UNUSED(data_path)) +static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree), + bNodeSocket *stemp, + bNode *UNUSED(node), + bNodeSocket *sock, + const char *UNUSED(data_path)) { - /* sanity check */ - if (sock->type != stemp->typeinfo->type) - return; - - /* make sure both exist */ - if (!stemp->default_value) - return; - node_socket_init_default_value(sock); - - switch (stemp->typeinfo->type) { - case SOCK_FLOAT: - { - bNodeSocketValueFloat *toval = sock->default_value; - bNodeSocketValueFloat *fromval = stemp->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_INT: - { - bNodeSocketValueInt *toval = sock->default_value; - bNodeSocketValueInt *fromval = stemp->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_VECTOR: - { - bNodeSocketValueVector *toval = sock->default_value; - bNodeSocketValueVector *fromval = stemp->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - } + /* sanity check */ + if (sock->type != stemp->typeinfo->type) + return; + + /* make sure both exist */ + if (!stemp->default_value) + return; + node_socket_init_default_value(sock); + + switch (stemp->typeinfo->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *toval = sock->default_value; + bNodeSocketValueFloat *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = sock->default_value; + bNodeSocketValueInt *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = sock->default_value; + bNodeSocketValueVector *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + } } -static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock) +static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree), + bNodeSocket *stemp, + bNode *UNUSED(node), + bNodeSocket *sock) { - /* initialize settings */ - stemp->type = stemp->typeinfo->type; - node_socket_copy_default_value(stemp, sock); + /* initialize settings */ + stemp->type = stemp->typeinfo->type; + node_socket_copy_default_value(stemp, sock); } static bNodeSocketType *make_standard_socket_type(int type, int subtype) { - extern void ED_init_standard_node_socket_type(bNodeSocketType *); + extern void ED_init_standard_node_socket_type(bNodeSocketType *); - const char *socket_idname = nodeStaticSocketType(type, subtype); - const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); - bNodeSocketType *stype; - StructRNA *srna; + const char *socket_idname = nodeStaticSocketType(type, subtype); + const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); + bNodeSocketType *stype; + StructRNA *srna; - stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); - BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); + stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); + BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); - /* set the RNA type - * uses the exact same identifier as the socket type idname */ - srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); - BLI_assert(srna != NULL); - /* associate the RNA type with the socket type */ - RNA_struct_blender_type_set(srna, stype); + /* set the RNA type + * uses the exact same identifier as the socket type idname */ + srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); + BLI_assert(srna != NULL); + /* associate the RNA type with the socket type */ + RNA_struct_blender_type_set(srna, stype); - /* set the interface RNA type */ - srna = stype->ext_interface.srna = RNA_struct_find(interface_idname); - BLI_assert(srna != NULL); - /* associate the RNA type with the socket type */ - RNA_struct_blender_type_set(srna, stype); + /* set the interface RNA type */ + srna = stype->ext_interface.srna = RNA_struct_find(interface_idname); + BLI_assert(srna != NULL); + /* associate the RNA type with the socket type */ + RNA_struct_blender_type_set(srna, stype); - /* extra type info for standard socket types */ - stype->type = type; - stype->subtype = subtype; + /* extra type info for standard socket types */ + stype->type = type; + stype->subtype = subtype; - /* XXX bad-level call! needed for setting draw callbacks */ - ED_init_standard_node_socket_type(stype); + /* XXX bad-level call! needed for setting draw callbacks */ + ED_init_standard_node_socket_type(stype); - stype->interface_init_socket = standard_node_socket_interface_init_socket; - stype->interface_from_socket = standard_node_socket_interface_from_socket; - stype->interface_verify_socket = standard_node_socket_interface_verify_socket; + stype->interface_init_socket = standard_node_socket_interface_init_socket; + stype->interface_from_socket = standard_node_socket_interface_from_socket; + stype->interface_verify_socket = standard_node_socket_interface_verify_socket; - return stype; + return stype; } static bNodeSocketType *make_socket_type_virtual(void) { - extern void ED_init_node_socket_type_virtual(bNodeSocketType *); + extern void ED_init_node_socket_type_virtual(bNodeSocketType *); - const char *socket_idname = "NodeSocketVirtual"; - bNodeSocketType *stype; - StructRNA *srna; + const char *socket_idname = "NodeSocketVirtual"; + bNodeSocketType *stype; + StructRNA *srna; - stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); - BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); + stype = MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); + BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname)); - /* set the RNA type - * uses the exact same identifier as the socket type idname */ - srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); - BLI_assert(srna != NULL); - /* associate the RNA type with the socket type */ - RNA_struct_blender_type_set(srna, stype); + /* set the RNA type + * uses the exact same identifier as the socket type idname */ + srna = stype->ext_socket.srna = RNA_struct_find(socket_idname); + BLI_assert(srna != NULL); + /* associate the RNA type with the socket type */ + RNA_struct_blender_type_set(srna, stype); - /* extra type info for standard socket types */ - stype->type = SOCK_CUSTOM; + /* extra type info for standard socket types */ + stype->type = SOCK_CUSTOM; - ED_init_node_socket_type_virtual(stype); + ED_init_node_socket_type_virtual(stype); - return stype; + return stype; } - void register_standard_node_socket_types(void) { - /* draw callbacks are set in drawnode.c to avoid bad-level calls */ + /* draw callbacks are set in drawnode.c to avoid bad-level calls */ - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_UNSIGNED)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_PERCENTAGE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_FACTOR)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_ANGLE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_TIME)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_UNSIGNED)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_PERCENTAGE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_FACTOR)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_ANGLE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_FLOAT, PROP_TIME)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_UNSIGNED)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_PERCENTAGE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_FACTOR)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_UNSIGNED)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_PERCENTAGE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_INT, PROP_FACTOR)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_BOOLEAN, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_TRANSLATION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_DIRECTION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_VELOCITY)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_ACCELERATION)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_EULER)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_XYZ)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_TRANSLATION)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_DIRECTION)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_VELOCITY)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_ACCELERATION)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_EULER)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_VECTOR, PROP_XYZ)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_RGBA, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_STRING, PROP_NONE)); - nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); + nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); - nodeRegisterSocketType(make_socket_type_virtual()); + nodeRegisterSocketType(make_socket_type_virtual()); } diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index 069a5bb599e..a4a39caf8df 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -47,164 +47,163 @@ void node_free_curves(bNode *node) { - curvemapping_free(node->storage); + curvemapping_free(node->storage); } void node_free_standard_storage(bNode *node) { - if (node->storage) { - MEM_freeN(node->storage); - } + if (node->storage) { + MEM_freeN(node->storage); + } } void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node) { - dest_node->storage = curvemapping_copy(src_node->storage); + dest_node->storage = curvemapping_copy(src_node->storage); } void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node) { - dest_node->storage = MEM_dupallocN(src_node->storage); + dest_node->storage = MEM_dupallocN(src_node->storage); } -void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNodeInstanceKey UNUSED(key)) +void *node_initexec_curves(bNodeExecContext *UNUSED(context), + bNode *node, + bNodeInstanceKey UNUSED(key)) { - curvemapping_initialize(node->storage); - return NULL; /* unused return */ + curvemapping_initialize(node->storage); + return NULL; /* unused return */ } - /**** Labels ****/ void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - const char *name; - RNA_enum_name(rna_enum_ramp_blend_items, node->custom1, &name); - BLI_strncpy(label, IFACE_(name), maxlen); + const char *name; + RNA_enum_name(rna_enum_ramp_blend_items, node->custom1, &name); + BLI_strncpy(label, IFACE_(name), maxlen); } void node_image_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - /* if there is no loaded image, return an empty string, and let nodeLabel() fill in the proper type translation. */ - BLI_strncpy(label, (node->id) ? node->id->name + 2 : "", maxlen); + /* if there is no loaded image, return an empty string, and let nodeLabel() fill in the proper type translation. */ + BLI_strncpy(label, (node->id) ? node->id->name + 2 : "", maxlen); } void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - const char *name; - RNA_enum_name(rna_enum_node_math_items, node->custom1, &name); - BLI_strncpy(label, IFACE_(name), maxlen); + const char *name; + RNA_enum_name(rna_enum_node_math_items, node->custom1, &name); + BLI_strncpy(label, IFACE_(name), maxlen); } void node_vect_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - const char *name; - RNA_enum_name(rna_enum_node_vec_math_items, node->custom1, &name); - BLI_strncpy(label, IFACE_(name), maxlen); + const char *name; + RNA_enum_name(rna_enum_node_vec_math_items, node->custom1, &name); + BLI_strncpy(label, IFACE_(name), maxlen); } void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { - const char *name; - RNA_enum_name(rna_enum_node_filter_items, node->custom1, &name); - BLI_strncpy(label, IFACE_(name), maxlen); + const char *name; + RNA_enum_name(rna_enum_node_filter_items, node->custom1, &name); + BLI_strncpy(label, IFACE_(name), maxlen); } - /*** Link Insertion ***/ /* test if two sockets are interchangeable */ static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b) { - /* check if sockets are of the same type */ - if (a->typeinfo != b->typeinfo) { - return false; - } - - /* tests if alphabetic prefix matches - * this allows for imperfect matches, such as numeric suffixes, - * like Color1/Color2 - */ - int prefix_len = 0; - char *ca = a->name, *cb = b->name; - for (; *ca != '\0' && *cb != '\0'; ++ca, ++cb) { - /* end of common prefix? */ - if (*ca != *cb) { - /* prefix delimited by non-alphabetic char */ - if (isalpha(*ca) || isalpha(*cb)) - return false; - break; - } - ++prefix_len; - } - return prefix_len > 0; + /* check if sockets are of the same type */ + if (a->typeinfo != b->typeinfo) { + return false; + } + + /* tests if alphabetic prefix matches + * this allows for imperfect matches, such as numeric suffixes, + * like Color1/Color2 + */ + int prefix_len = 0; + char *ca = a->name, *cb = b->name; + for (; *ca != '\0' && *cb != '\0'; ++ca, ++cb) { + /* end of common prefix? */ + if (*ca != *cb) { + /* prefix delimited by non-alphabetic char */ + if (isalpha(*ca) || isalpha(*cb)) + return false; + break; + } + ++prefix_len; + } + return prefix_len > 0; } static int node_count_links(bNodeTree *ntree, bNodeSocket *sock) { - bNodeLink *link; - int count = 0; - for (link = ntree->links.first; link; link = link->next) { - if (link->fromsock == sock) - ++count; - if (link->tosock == sock) - ++count; - } - return count; + bNodeLink *link; + int count = 0; + for (link = ntree->links.first; link; link = link->next) { + if (link->fromsock == sock) + ++count; + if (link->tosock == sock) + ++count; + } + return count; } /* find an eligible socket for linking */ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur) { - /* link swapping: try to find a free slot with a matching name */ - - bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first; - bNodeSocket *sock; - - sock = cur->next ? cur->next : first; /* wrap around the list end */ - while (sock != cur) { - if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) { - int link_count = node_count_links(ntree, sock); - /* take +1 into account since we would add a new link */ - if (link_count + 1 <= sock->limit) - return sock; /* found a valid free socket we can swap to */ - } - - sock = sock->next ? sock->next : first; /* wrap around the list end */ - } - return NULL; + /* link swapping: try to find a free slot with a matching name */ + + bNodeSocket *first = cur->in_out == SOCK_IN ? node->inputs.first : node->outputs.first; + bNodeSocket *sock; + + sock = cur->next ? cur->next : first; /* wrap around the list end */ + while (sock != cur) { + if (!nodeSocketIsHidden(sock) && node_link_socket_match(sock, cur)) { + int link_count = node_count_links(ntree, sock); + /* take +1 into account since we would add a new link */ + if (link_count + 1 <= sock->limit) + return sock; /* found a valid free socket we can swap to */ + } + + sock = sock->next ? sock->next : first; /* wrap around the list end */ + } + return NULL; } void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) { - bNodeSocket *sock = link->tosock; - bNodeLink *tlink, *tlink_next; - - /* inputs can have one link only, outputs can have unlimited links */ - if (node != link->tonode) - return; - - for (tlink = ntree->links.first; tlink; tlink = tlink_next) { - bNodeSocket *new_sock; - tlink_next = tlink->next; - - if (sock != tlink->tosock) - continue; - - new_sock = node_find_linkable_socket(ntree, node, sock); - if (new_sock && new_sock != sock) { - /* redirect existing link */ - tlink->tosock = new_sock; - } - else if (!new_sock) { - /* no possible replacement, remove tlink */ - nodeRemLink(ntree, tlink); - tlink = NULL; - } - } + bNodeSocket *sock = link->tosock; + bNodeLink *tlink, *tlink_next; + + /* inputs can have one link only, outputs can have unlimited links */ + if (node != link->tonode) + return; + + for (tlink = ntree->links.first; tlink; tlink = tlink_next) { + bNodeSocket *new_sock; + tlink_next = tlink->next; + + if (sock != tlink->tosock) + continue; + + new_sock = node_find_linkable_socket(ntree, node, sock); + if (new_sock && new_sock != sock) { + /* redirect existing link */ + tlink->tosock = new_sock; + } + else if (!new_sock) { + /* no possible replacement, remove tlink */ + nodeRemLink(ntree, tlink); + tlink = NULL; + } + } } - /**** Internal Links (mute and disconnect) ****/ /* common datatype priorities, works for compositor, shader and texture nodes alike @@ -214,184 +213,223 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) */ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to) { - switch (to) { - case SOCK_RGBA: - switch (from) { - case SOCK_RGBA: return 4; - case SOCK_FLOAT: return 3; - case SOCK_INT: return 2; - case SOCK_BOOLEAN: return 1; - default: return -1; - } - case SOCK_VECTOR: - switch (from) { - case SOCK_VECTOR: return 4; - case SOCK_FLOAT: return 3; - case SOCK_INT: return 2; - case SOCK_BOOLEAN: return 1; - default: return -1; - } - case SOCK_FLOAT: - switch (from) { - case SOCK_FLOAT: return 5; - case SOCK_INT: return 4; - case SOCK_BOOLEAN: return 3; - case SOCK_RGBA: return 2; - case SOCK_VECTOR: return 1; - default: return -1; - } - case SOCK_INT: - switch (from) { - case SOCK_INT: return 5; - case SOCK_FLOAT: return 4; - case SOCK_BOOLEAN: return 3; - case SOCK_RGBA: return 2; - case SOCK_VECTOR: return 1; - default: return -1; - } - case SOCK_BOOLEAN: - switch (from) { - case SOCK_BOOLEAN: return 5; - case SOCK_INT: return 4; - case SOCK_FLOAT: return 3; - case SOCK_RGBA: return 2; - case SOCK_VECTOR: return 1; - default: return -1; - } - case SOCK_SHADER: - switch (from) { - case SOCK_SHADER: return 1; - default: return -1; - } - case SOCK_STRING: - switch (from) { - case SOCK_STRING: return 1; - default: return -1; - } - default: return -1; - } + switch (to) { + case SOCK_RGBA: + switch (from) { + case SOCK_RGBA: + return 4; + case SOCK_FLOAT: + return 3; + case SOCK_INT: + return 2; + case SOCK_BOOLEAN: + return 1; + default: + return -1; + } + case SOCK_VECTOR: + switch (from) { + case SOCK_VECTOR: + return 4; + case SOCK_FLOAT: + return 3; + case SOCK_INT: + return 2; + case SOCK_BOOLEAN: + return 1; + default: + return -1; + } + case SOCK_FLOAT: + switch (from) { + case SOCK_FLOAT: + return 5; + case SOCK_INT: + return 4; + case SOCK_BOOLEAN: + return 3; + case SOCK_RGBA: + return 2; + case SOCK_VECTOR: + return 1; + default: + return -1; + } + case SOCK_INT: + switch (from) { + case SOCK_INT: + return 5; + case SOCK_FLOAT: + return 4; + case SOCK_BOOLEAN: + return 3; + case SOCK_RGBA: + return 2; + case SOCK_VECTOR: + return 1; + default: + return -1; + } + case SOCK_BOOLEAN: + switch (from) { + case SOCK_BOOLEAN: + return 5; + case SOCK_INT: + return 4; + case SOCK_FLOAT: + return 3; + case SOCK_RGBA: + return 2; + case SOCK_VECTOR: + return 1; + default: + return -1; + } + case SOCK_SHADER: + switch (from) { + case SOCK_SHADER: + return 1; + default: + return -1; + } + case SOCK_STRING: + switch (from) { + case SOCK_STRING: + return 1; + default: + return -1; + } + default: + return -1; + } } /* select a suitable input socket for an output */ static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output) { - bNodeSocket *selected = NULL, *input; - int i; - int sel_priority = -1; - bool sel_is_linked = false; - - for (input = node->inputs.first, i = 0; input; input = input->next, ++i) { - int priority = node_datatype_priority(input->type, output->type); - bool is_linked = (input->link != NULL); - bool preferred; - - if (nodeSocketIsHidden(input) || /* ignore hidden sockets */ - input->flag & SOCK_NO_INTERNAL_LINK || /* ignore if input is not allowed for internal connections */ - priority < 0 || /* ignore incompatible types */ - priority < sel_priority) /* ignore if we already found a higher priority input */ - { - continue; - } - - /* determine if this input is preferred over the currently selected */ - preferred = (priority > sel_priority) || /* prefer higher datatype priority */ - (is_linked && !sel_is_linked); /* prefer linked over unlinked */ - - if (preferred) { - selected = input; - sel_is_linked = is_linked; - sel_priority = priority; - } - } - - return selected; + bNodeSocket *selected = NULL, *input; + int i; + int sel_priority = -1; + bool sel_is_linked = false; + + for (input = node->inputs.first, i = 0; input; input = input->next, ++i) { + int priority = node_datatype_priority(input->type, output->type); + bool is_linked = (input->link != NULL); + bool preferred; + + if (nodeSocketIsHidden(input) || /* ignore hidden sockets */ + input->flag & + SOCK_NO_INTERNAL_LINK || /* ignore if input is not allowed for internal connections */ + priority < 0 || /* ignore incompatible types */ + priority < sel_priority) /* ignore if we already found a higher priority input */ + { + continue; + } + + /* determine if this input is preferred over the currently selected */ + preferred = (priority > sel_priority) || /* prefer higher datatype priority */ + (is_linked && !sel_is_linked); /* prefer linked over unlinked */ + + if (preferred) { + selected = input; + sel_is_linked = is_linked; + sel_priority = priority; + } + } + + return selected; } void node_update_internal_links_default(bNodeTree *ntree, bNode *node) { - bNodeLink *link; - bNodeSocket *output, *input; - - /* sanity check */ - if (!ntree) - return; - - /* use link pointer as a tag for handled sockets (for outputs is unused anyway) */ - for (output = node->outputs.first; output; output = output->next) - output->link = NULL; - - for (link = ntree->links.first; link; link = link->next) { - if (nodeLinkIsHidden(link)) - continue; - - output = link->fromsock; - if (link->fromnode != node || output->link) - continue; - if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK) - continue; - output->link = link; /* not really used, just for tagging handled sockets */ - - /* look for suitable input */ - input = select_internal_link_input(node, output); - - if (input) { - bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link"); - ilink->fromnode = node; - ilink->fromsock = input; - ilink->tonode = node; - ilink->tosock = output; - /* internal link is always valid */ - ilink->flag |= NODE_LINK_VALID; - BLI_addtail(&node->internal_links, ilink); - } - } - - /* clean up */ - for (output = node->outputs.first; output; output = output->next) - output->link = NULL; + bNodeLink *link; + bNodeSocket *output, *input; + + /* sanity check */ + if (!ntree) + return; + + /* use link pointer as a tag for handled sockets (for outputs is unused anyway) */ + for (output = node->outputs.first; output; output = output->next) + output->link = NULL; + + for (link = ntree->links.first; link; link = link->next) { + if (nodeLinkIsHidden(link)) + continue; + + output = link->fromsock; + if (link->fromnode != node || output->link) + continue; + if (nodeSocketIsHidden(output) || output->flag & SOCK_NO_INTERNAL_LINK) + continue; + output->link = link; /* not really used, just for tagging handled sockets */ + + /* look for suitable input */ + input = select_internal_link_input(node, output); + + if (input) { + bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link"); + ilink->fromnode = node; + ilink->fromsock = input; + ilink->tonode = node; + ilink->tosock = output; + /* internal link is always valid */ + ilink->flag |= NODE_LINK_VALID; + BLI_addtail(&node->internal_links, ilink); + } + } + + /* clean up */ + for (output = node->outputs.first; output; output = output->next) + output->link = NULL; } - /**** Default value RNA access ****/ float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - return RNA_float_get(&ptr, "default_value"); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + return RNA_float_get(&ptr, "default_value"); } void node_socket_set_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float value) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - RNA_float_set(&ptr, "default_value", value); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_float_set(&ptr, "default_value", value); } void node_socket_get_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - RNA_float_get_array(&ptr, "default_value", value); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_float_get_array(&ptr, "default_value", value); } -void node_socket_set_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, const float *value) +void node_socket_set_color(bNodeTree *ntree, + bNode *UNUSED(node), + bNodeSocket *sock, + const float *value) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - RNA_float_set_array(&ptr, "default_value", value); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_float_set_array(&ptr, "default_value", value); } void node_socket_get_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - RNA_float_get_array(&ptr, "default_value", value); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_float_get_array(&ptr, "default_value", value); } -void node_socket_set_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, const float *value) +void node_socket_set_vector(bNodeTree *ntree, + bNode *UNUSED(node), + bNodeSocket *sock, + const float *value) { - PointerRNA ptr; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); - RNA_float_set_array(&ptr, "default_value", value); + PointerRNA ptr; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); + RNA_float_set_array(&ptr, "default_value", value); } diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index 00b2063804b..ec5cd074922 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -21,7 +21,6 @@ * \ingroup nodes */ - #ifndef __NODE_UTIL_H__ #define __NODE_UTIL_H__ @@ -44,12 +43,12 @@ struct bNodeTree; /* data for initializing node execution */ typedef struct bNodeExecContext { - struct bNodeInstanceHash *previews; + struct bNodeInstanceHash *previews; } bNodeExecContext; typedef struct bNodeExecData { - void *data; /* custom data storage */ - struct bNodePreview *preview; /* optional preview image */ + void *data; /* custom data storage */ + struct bNodePreview *preview; /* optional preview image */ } bNodeExecData; /**** Storage Data ****/ @@ -57,9 +56,15 @@ typedef struct bNodeExecData { extern void node_free_curves(struct bNode *node); extern void node_free_standard_storage(struct bNode *node); -extern void node_copy_curves(struct bNodeTree *dest_ntree, struct bNode *dest_node, struct bNode *src_node); -extern void node_copy_standard_storage(struct bNodeTree *dest_ntree, struct bNode *dest_node, struct bNode *src_node); -extern void *node_initexec_curves(struct bNodeExecContext *context, struct bNode *node, bNodeInstanceKey key); +extern void node_copy_curves(struct bNodeTree *dest_ntree, + struct bNode *dest_node, + struct bNode *src_node); +extern void node_copy_standard_storage(struct bNodeTree *dest_ntree, + struct bNode *dest_node, + struct bNode *src_node); +extern void *node_initexec_curves(struct bNodeExecContext *context, + struct bNode *node, + bNodeInstanceKey key); /**** Labels ****/ @@ -69,16 +74,30 @@ void node_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, i void node_vect_math_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); void node_filter_label(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); - /*** Link Handling */ void node_insert_link_default(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); void node_update_internal_links_default(struct bNodeTree *ntree, struct bNode *node); float node_socket_get_float(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); -void node_socket_set_float(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, float value); -void node_socket_get_color(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, float *value); -void node_socket_set_color(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, const float *value); -void node_socket_get_vector(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, float *value); -void node_socket_set_vector(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, const float *value); +void node_socket_set_float(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + float value); +void node_socket_get_color(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + float *value); +void node_socket_set_color(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + const float *value); +void node_socket_get_vector(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + float *value); +void node_socket_set_vector(struct bNodeTree *ntree, + struct bNode *node, + struct bNodeSocket *sock, + const float *value); #endif |