forked from bartvdbraak/blender
Node callback for handling link insertion and swapping of occupied inputs.
Nodes have a feature for moving existing links to unoccupied sockets when connecting to an already used input. This is based on the standard legacy socket types (value/float, vector, color/rgba) and works reasonably well for shader, compositor and texture nodes. For new pynode systems, however, the hardcoded nature of that feature has major drawbacks: * It does not take different type systems into account, leading to meaningless connections when sockets are swapped and making the feature useless or outright debilitating. * Advanced socket behaviors would be possible with a registerable callback, e.g. creating extensible input lists that move existing connections down to make room for a new link. Now any handling of new links is done via the 'insert_links' callback, which can also be registered through the RNA API. For the legacy shader/compo/tex nodes the behavior is the same, using a C callback. Note on the 'use_swap' flag: this has been removed because it was meaningless anyway: It was disabled only for the insert-node-on-link feature, which works only for completely unconnected nodes anyway, so there would be nothing to swap in the first place.
This commit is contained in:
parent
762aad3777
commit
7f759ec547
@ -206,6 +206,8 @@ typedef struct bNodeType {
|
|||||||
/* can this node be added to a node tree */
|
/* can this node be added to a node tree */
|
||||||
int (*poll_instance)(struct bNode *node, struct bNodeTree *nodetree);
|
int (*poll_instance)(struct bNode *node, struct bNodeTree *nodetree);
|
||||||
|
|
||||||
|
/* optional handling of link insertion */
|
||||||
|
void (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link);
|
||||||
/* Update the internal links list, for muting and disconnect operators. */
|
/* Update the internal links list, for muting and disconnect operators. */
|
||||||
void (*update_internal_links)(struct bNodeTree *, struct bNode *node);
|
void (*update_internal_links)(struct bNodeTree *, struct bNode *node);
|
||||||
|
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
* \ingroup spnode
|
* \ingroup spnode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "DNA_node_types.h"
|
#include "DNA_node_types.h"
|
||||||
@ -420,7 +418,6 @@ static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
|
|||||||
#undef HEADER_LENGTH
|
#undef HEADER_LENGTH
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update link_count fields to avoid repeated link counting */
|
|
||||||
static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
|
static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
|
||||||
{
|
{
|
||||||
bNodeLink *link;
|
bNodeLink *link;
|
||||||
@ -434,64 +431,13 @@ static int node_count_links(bNodeTree *ntree, bNodeSocket *sock)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test if two sockets are interchangeable
|
static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
|
||||||
* XXX this could be made into a tree-type callback for flexibility
|
|
||||||
*/
|
|
||||||
static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find an eligible socket for linking */
|
|
||||||
static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, bNode *node, bNodeSocket *cur, bool use_swap)
|
|
||||||
{
|
|
||||||
int cur_link_count = node_count_links(ntree, cur);
|
|
||||||
if (cur_link_count <= cur->limit) {
|
|
||||||
/* current socket is fine, use it */
|
|
||||||
return cur;
|
|
||||||
}
|
|
||||||
else if (use_swap) {
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link, bool use_swap)
|
|
||||||
{
|
{
|
||||||
bNodeTree *ntree = snode->edittree;
|
bNodeTree *ntree = snode->edittree;
|
||||||
bNodeSocket *from = link->fromsock, *to = link->tosock;
|
bNodeSocket *from = link->fromsock, *to = link->tosock;
|
||||||
bNodeLink *tlink, *tlink_next;
|
bNodeLink *tlink, *tlink_next;
|
||||||
|
int to_count = node_count_links(ntree, to);
|
||||||
|
int from_count = node_count_links(ntree, from);
|
||||||
|
|
||||||
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
|
for (tlink = ntree->links.first; tlink; tlink = tlink_next) {
|
||||||
tlink_next = tlink->next;
|
tlink_next = tlink->next;
|
||||||
@ -499,28 +445,18 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link, bool use_
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (tlink && tlink->fromsock == from) {
|
if (tlink && tlink->fromsock == from) {
|
||||||
bNodeSocket *new_from = node_find_linkable_socket(ntree, tlink->fromnode, from, use_swap);
|
if (from_count > from->limit) {
|
||||||
if (new_from && new_from != from) {
|
|
||||||
/* redirect existing link */
|
|
||||||
tlink->fromsock = new_from;
|
|
||||||
}
|
|
||||||
else if (!new_from) {
|
|
||||||
/* no possible replacement, remove tlink */
|
|
||||||
nodeRemLink(ntree, tlink);
|
nodeRemLink(ntree, tlink);
|
||||||
tlink = NULL;
|
tlink = NULL;
|
||||||
|
--from_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlink && tlink->tosock == to) {
|
if (tlink && tlink->tosock == to) {
|
||||||
bNodeSocket *new_to = node_find_linkable_socket(ntree, tlink->tonode, to, use_swap);
|
if (to_count > to->limit) {
|
||||||
if (new_to && new_to != to) {
|
|
||||||
/* redirect existing link */
|
|
||||||
tlink->tosock = new_to;
|
|
||||||
}
|
|
||||||
else if (!new_to) {
|
|
||||||
/* no possible replacement, remove tlink */
|
|
||||||
nodeRemLink(ntree, tlink);
|
nodeRemLink(ntree, tlink);
|
||||||
tlink = NULL;
|
tlink = NULL;
|
||||||
|
--to_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,6 +473,14 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
|
|||||||
bNodeLink *link = linkdata->data;
|
bNodeLink *link = linkdata->data;
|
||||||
|
|
||||||
if (apply_links && link->tosock && link->fromsock) {
|
if (apply_links && link->tosock && link->fromsock) {
|
||||||
|
/* before actually adding the link,
|
||||||
|
* let nodes perform special link insertion handling
|
||||||
|
*/
|
||||||
|
if (link->fromnode->typeinfo->insert_link)
|
||||||
|
link->fromnode->typeinfo->insert_link(ntree, link->fromnode, link);
|
||||||
|
if (link->tonode->typeinfo->insert_link)
|
||||||
|
link->tonode->typeinfo->insert_link(ntree, link->tonode, link);
|
||||||
|
|
||||||
/* add link to the node tree */
|
/* add link to the node tree */
|
||||||
BLI_addtail(&ntree->links, link);
|
BLI_addtail(&ntree->links, link);
|
||||||
|
|
||||||
@ -546,7 +490,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
|
|||||||
link->tonode->update |= NODE_UPDATE;
|
link->tonode->update |= NODE_UPDATE;
|
||||||
|
|
||||||
/* we might need to remove a link */
|
/* we might need to remove a link */
|
||||||
node_remove_extra_links(snode, link, true);
|
node_remove_extra_links(snode, link);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nodeRemLink(ntree, link);
|
nodeRemLink(ntree, link);
|
||||||
@ -1746,7 +1690,7 @@ void ED_node_link_insert(ScrArea *sa)
|
|||||||
|
|
||||||
link->tonode = select;
|
link->tonode = select;
|
||||||
link->tosock = best_input;
|
link->tosock = best_input;
|
||||||
node_remove_extra_links(snode, link, false);
|
node_remove_extra_links(snode, link);
|
||||||
link->flag &= ~NODE_LINKFLAG_HILITE;
|
link->flag &= ~NODE_LINKFLAG_HILITE;
|
||||||
|
|
||||||
nodeAddLink(snode->edittree, select, best_output, node, sockto);
|
nodeAddLink(snode->edittree, select, best_output, node, sockto);
|
||||||
|
@ -1182,6 +1182,24 @@ static void rna_Node_update_reg(bNodeTree *ntree, bNode *node)
|
|||||||
RNA_parameter_list_free(&list);
|
RNA_parameter_list_free(&list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_Node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link)
|
||||||
|
{
|
||||||
|
extern FunctionRNA rna_Node_insert_link_func;
|
||||||
|
|
||||||
|
PointerRNA ptr;
|
||||||
|
ParameterList list;
|
||||||
|
FunctionRNA *func;
|
||||||
|
|
||||||
|
RNA_pointer_create((ID *)ntree, node->typeinfo->ext.srna, node, &ptr);
|
||||||
|
func = &rna_Node_insert_link_func;
|
||||||
|
|
||||||
|
RNA_parameter_list_create(&list, &ptr, func);
|
||||||
|
RNA_parameter_set_lookup(&list, "link", &link);
|
||||||
|
node->typeinfo->ext.call(NULL, &ptr, func, &list);
|
||||||
|
|
||||||
|
RNA_parameter_list_free(&list);
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_Node_init(const bContext *C, PointerRNA *ptr)
|
static void rna_Node_init(const bContext *C, PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
extern FunctionRNA rna_Node_init_func;
|
extern FunctionRNA rna_Node_init_func;
|
||||||
@ -1384,12 +1402,13 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc
|
|||||||
nt->poll = (have_function[0]) ? rna_Node_poll : NULL;
|
nt->poll = (have_function[0]) ? rna_Node_poll : NULL;
|
||||||
nt->poll_instance = (have_function[1]) ? rna_Node_poll_instance : rna_Node_poll_instance_default;
|
nt->poll_instance = (have_function[1]) ? rna_Node_poll_instance : rna_Node_poll_instance_default;
|
||||||
nt->updatefunc = (have_function[2]) ? rna_Node_update_reg : NULL;
|
nt->updatefunc = (have_function[2]) ? rna_Node_update_reg : NULL;
|
||||||
nt->initfunc_api = (have_function[3]) ? rna_Node_init : NULL;
|
nt->insert_link = (have_function[3]) ? rna_Node_insert_link : NULL;
|
||||||
nt->copyfunc_api = (have_function[4]) ? rna_Node_copy : NULL;
|
nt->initfunc_api = (have_function[4]) ? rna_Node_init : NULL;
|
||||||
nt->freefunc_api = (have_function[5]) ? rna_Node_free : NULL;
|
nt->copyfunc_api = (have_function[5]) ? rna_Node_copy : NULL;
|
||||||
nt->draw_buttons = (have_function[6]) ? rna_Node_draw_buttons : NULL;
|
nt->freefunc_api = (have_function[6]) ? rna_Node_free : NULL;
|
||||||
nt->draw_buttons_ex = (have_function[7]) ? rna_Node_draw_buttons_ext : NULL;
|
nt->draw_buttons = (have_function[7]) ? rna_Node_draw_buttons : NULL;
|
||||||
nt->labelfunc = (have_function[8]) ? rna_Node_draw_label : NULL;
|
nt->draw_buttons_ex = (have_function[8]) ? rna_Node_draw_buttons_ext : NULL;
|
||||||
|
nt->labelfunc = (have_function[9]) ? rna_Node_draw_label : NULL;
|
||||||
|
|
||||||
/* sanitize size values in case not all have been registered */
|
/* sanitize size values in case not all have been registered */
|
||||||
if (nt->maxwidth < nt->minwidth)
|
if (nt->maxwidth < nt->minwidth)
|
||||||
@ -7706,6 +7725,13 @@ static void rna_def_node(BlenderRNA *brna)
|
|||||||
RNA_def_function_ui_description(func, "Update on editor changes");
|
RNA_def_function_ui_description(func, "Update on editor changes");
|
||||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
|
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
|
||||||
|
|
||||||
|
/* insert_link */
|
||||||
|
func = RNA_def_function(srna, "insert_link", NULL);
|
||||||
|
RNA_def_function_ui_description(func, "Handle creation of a link to or from the node");
|
||||||
|
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_REGISTER_OPTIONAL);
|
||||||
|
parm = RNA_def_pointer(func, "link", "NodeLink", "Link", "Node link that will be inserted");
|
||||||
|
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
func = RNA_def_function(srna, "init", NULL);
|
func = RNA_def_function(srna, "init", NULL);
|
||||||
RNA_def_function_ui_description(func, "Initialize a new instance of this node");
|
RNA_def_function_ui_description(func, "Initialize a new instance of this node");
|
||||||
|
@ -55,5 +55,6 @@ void cmp_node_type_base(bNodeType *ntype, int type, const char *name, short ncla
|
|||||||
|
|
||||||
ntype->poll = cmp_node_poll_default;
|
ntype->poll = cmp_node_poll_default;
|
||||||
ntype->updatefunc = cmp_node_update_default;
|
ntype->updatefunc = cmp_node_update_default;
|
||||||
|
ntype->insert_link = node_insert_link_default;
|
||||||
ntype->update_internal_links = node_update_internal_links_default;
|
ntype->update_internal_links = node_update_internal_links_default;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ void register_node_type_cmp_group(void)
|
|||||||
ntype.type = NODE_GROUP;
|
ntype.type = NODE_GROUP;
|
||||||
ntype.poll = cmp_node_poll_default;
|
ntype.poll = cmp_node_poll_default;
|
||||||
ntype.poll_instance = node_group_poll_instance;
|
ntype.poll_instance = node_group_poll_instance;
|
||||||
|
ntype.insert_link = node_insert_link_default;
|
||||||
ntype.update_internal_links = node_update_internal_links_default;
|
ntype.update_internal_links = node_update_internal_links_default;
|
||||||
ntype.ext.srna = RNA_struct_find("CompositorNodeGroup");
|
ntype.ext.srna = RNA_struct_find("CompositorNodeGroup");
|
||||||
BLI_assert(ntype.ext.srna != NULL);
|
BLI_assert(ntype.ext.srna != NULL);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
* \ingroup nodes
|
* \ingroup nodes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -112,6 +113,95 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** Link Insertion ***/
|
||||||
|
|
||||||
|
/* test if two sockets are interchangeable */
|
||||||
|
static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b)
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**** Internal Links (mute and disconnect) ****/
|
/**** Internal Links (mute and disconnect) ****/
|
||||||
|
|
||||||
/* common datatype priorities, works for compositor, shader and texture nodes alike
|
/* common datatype priorities, works for compositor, shader and texture nodes alike
|
||||||
|
@ -76,6 +76,9 @@ 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_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);
|
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);
|
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);
|
float node_socket_get_float(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock);
|
||||||
|
@ -47,6 +47,7 @@ void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, shor
|
|||||||
node_type_base(ntype, type, name, nclass, flag);
|
node_type_base(ntype, type, name, nclass, flag);
|
||||||
|
|
||||||
ntype->poll = sh_node_poll_default;
|
ntype->poll = sh_node_poll_default;
|
||||||
|
ntype->insert_link = node_insert_link_default;
|
||||||
ntype->update_internal_links = node_update_internal_links_default;
|
ntype->update_internal_links = node_update_internal_links_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +236,7 @@ void register_node_type_sh_group(void)
|
|||||||
ntype.type = NODE_GROUP;
|
ntype.type = NODE_GROUP;
|
||||||
ntype.poll = sh_node_poll_default;
|
ntype.poll = sh_node_poll_default;
|
||||||
ntype.poll_instance = node_group_poll_instance;
|
ntype.poll_instance = node_group_poll_instance;
|
||||||
|
ntype.insert_link = node_insert_link_default;
|
||||||
ntype.update_internal_links = node_update_internal_links_default;
|
ntype.update_internal_links = node_update_internal_links_default;
|
||||||
ntype.ext.srna = RNA_struct_find("ShaderNodeGroup");
|
ntype.ext.srna = RNA_struct_find("ShaderNodeGroup");
|
||||||
BLI_assert(ntype.ext.srna != NULL);
|
BLI_assert(ntype.ext.srna != NULL);
|
||||||
|
@ -60,6 +60,7 @@ void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, sho
|
|||||||
node_type_base(ntype, type, name, nclass, flag);
|
node_type_base(ntype, type, name, nclass, flag);
|
||||||
|
|
||||||
ntype->poll = tex_node_poll_default;
|
ntype->poll = tex_node_poll_default;
|
||||||
|
ntype->insert_link = node_insert_link_default;
|
||||||
ntype->update_internal_links = node_update_internal_links_default;
|
ntype->update_internal_links = node_update_internal_links_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ void register_node_type_tex_group(void)
|
|||||||
ntype.type = NODE_GROUP;
|
ntype.type = NODE_GROUP;
|
||||||
ntype.poll = tex_node_poll_default;
|
ntype.poll = tex_node_poll_default;
|
||||||
ntype.poll_instance = node_group_poll_instance;
|
ntype.poll_instance = node_group_poll_instance;
|
||||||
|
ntype.insert_link = node_insert_link_default;
|
||||||
ntype.update_internal_links = node_update_internal_links_default;
|
ntype.update_internal_links = node_update_internal_links_default;
|
||||||
ntype.ext.srna = RNA_struct_find("TextureNodeGroup");
|
ntype.ext.srna = RNA_struct_find("TextureNodeGroup");
|
||||||
BLI_assert(ntype.ext.srna != NULL);
|
BLI_assert(ntype.ext.srna != NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user