Nodes: Support internal links for custom sockets

Currently, nodes with custom sockets do not get their internal links
populated. So operators like Delete And Reconnect don't work with such
nodes. This patch put custom sockets into consideration when computing
priorities for internal links such that sockets of the same idname get
connected. Additionally, the patch cleanup the function in the process
to avoid redundant code repetition.

Reviewed By: Jacques Lucke

Differential Revision: https://developer.blender.org/D13386
This commit is contained in:
Omar Emara 2021-11-29 13:01:53 +02:00
parent ab2a7aa0da
commit f1118ee51e
1 changed files with 20 additions and 81 deletions

View File

@ -351,11 +351,11 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link)
* `< 0`: never connect these types.
* `>= 0`: priority of connection (higher values chosen first).
*/
static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to)
static int node_datatype_priority(const bNodeSocketType *from, const bNodeSocketType *to)
{
switch (to) {
switch (to->type) {
case SOCK_RGBA:
switch (from) {
switch (from->type) {
case SOCK_RGBA:
return 4;
case SOCK_FLOAT:
@ -364,11 +364,10 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
return 2;
case SOCK_BOOLEAN:
return 1;
default:
return -1;
}
return -1;
case SOCK_VECTOR:
switch (from) {
switch (from->type) {
case SOCK_VECTOR:
return 4;
case SOCK_FLOAT:
@ -377,11 +376,10 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
return 2;
case SOCK_BOOLEAN:
return 1;
default:
return -1;
}
return -1;
case SOCK_FLOAT:
switch (from) {
switch (from->type) {
case SOCK_FLOAT:
return 5;
case SOCK_INT:
@ -392,11 +390,10 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
return 2;
case SOCK_VECTOR:
return 1;
default:
return -1;
}
return -1;
case SOCK_INT:
switch (from) {
switch (from->type) {
case SOCK_INT:
return 5;
case SOCK_FLOAT:
@ -407,11 +404,10 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
return 2;
case SOCK_VECTOR:
return 1;
default:
return -1;
}
return -1;
case SOCK_BOOLEAN:
switch (from) {
switch (from->type) {
case SOCK_BOOLEAN:
return 5;
case SOCK_INT:
@ -422,74 +418,17 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
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;
}
case SOCK_OBJECT: {
switch (from) {
case SOCK_OBJECT:
return 1;
default:
return -1;
}
}
case SOCK_GEOMETRY: {
switch (from) {
case SOCK_GEOMETRY:
return 1;
default:
return -1;
}
}
case SOCK_COLLECTION: {
switch (from) {
case SOCK_COLLECTION:
return 1;
default:
return -1;
}
}
case SOCK_TEXTURE: {
switch (from) {
case SOCK_TEXTURE:
return 1;
default:
return -1;
}
}
case SOCK_IMAGE: {
switch (from) {
case SOCK_IMAGE:
return 1;
default:
return -1;
}
}
case SOCK_MATERIAL: {
switch (from) {
case SOCK_MATERIAL:
return 1;
default:
return -1;
}
}
default:
return -1;
}
/* The rest of the socket types only allow an internal link if both the input and output socket
* have the same type. If the sockets are custom, we check the idname instead. */
if (to->type == from->type && (to->type != SOCK_CUSTOM || STREQ(to->idname, from->idname))) {
return 1;
}
return -1;
}
/* select a suitable input socket for an output */
@ -505,7 +444,7 @@ static bNodeSocket *select_internal_link_input(bNode *node, bNodeSocket *output)
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);
int priority = node_datatype_priority(input->typeinfo, output->typeinfo);
bool is_linked = (input->link != NULL);
bool preferred;