void node_group_expose_all_sockets(bNodeTree *ngroup) { bNode *node; bNodeSocket *sock, *gsock; for (node=ngroup->nodes.first; node; node=node->next) { for (sock=node->inputs.first; sock; sock=sock->next) { if (!sock->link && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); /* initialize the default value. */ node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); } } for (sock=node->outputs.first; sock; sock=sock->next) { if (nodeCountSocketLinks(ngroup, sock)==0 && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); /* initialize the default value. */ node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); } } } }
/* 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; }
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; }