From 3aced11d79cd44c17732e80bf997f700df341bc4 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 29 Jun 2020 17:36:06 +0200 Subject: Nodes: rename node_socket.c to node_socket.cc I have to add some C++ code in callbacks for socket types for the new particle system. --- source/blender/makesrna/intern/rna_nodetree.c | 2 +- source/blender/nodes/CMakeLists.txt | 2 +- source/blender/nodes/NOD_socket.h | 8 + source/blender/nodes/intern/node_socket.c | 557 -------------------------- source/blender/nodes/intern/node_socket.cc | 557 ++++++++++++++++++++++++++ 5 files changed, 567 insertions(+), 559 deletions(-) delete mode 100644 source/blender/nodes/intern/node_socket.c create mode 100644 source/blender/nodes/intern/node_socket.cc (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index f17e7fe39e0..6312c84cf9f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -9020,7 +9020,7 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna) /* XXX These types should eventually be registered at runtime. * Then use the nodeStaticSocketType and nodeStaticSocketInterfaceType functions * to get the idname strings from int type and subtype - * (see node_socket.c, register_standard_node_socket_types). + * (see node_socket.cc, register_standard_node_socket_types). */ rna_def_node_socket_float(brna, "NodeSocketFloat", "NodeSocketInterfaceFloat", PROP_NONE); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 80bf0f7c5e2..31b5e922dab 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -273,7 +273,7 @@ set(SRC intern/node_common.c intern/node_exec.c - intern/node_socket.c + intern/node_socket.cc intern/node_util.c composite/node_composite_util.h diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h index b1b1a0e40c6..ce6f0da4aee 100644 --- a/source/blender/nodes/NOD_socket.h +++ b/source/blender/nodes/NOD_socket.h @@ -35,6 +35,10 @@ struct bNode; struct bNodeTree; +#ifdef __cplusplus +extern "C" { +#endif + struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp, @@ -46,4 +50,8 @@ void node_socket_init_default_value(struct bNodeSocket *sock); void node_socket_copy_default_value(struct bNodeSocket *to, const struct bNodeSocket *from); void register_standard_node_socket_types(void); +#ifdef __cplusplus +} #endif + +#endif /* __NOD_SOCKET_H__ */ diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c deleted file mode 100644 index 529fc036c7c..00000000000 --- a/source/blender/nodes/intern/node_socket.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2007 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup nodes - */ - -#include - -#include "DNA_node_types.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_utildefines.h" - -#include "BKE_lib_id.h" -#include "BKE_node.h" - -#include "RNA_access.h" -#include "RNA_types.h" - -#include "MEM_guardedalloc.h" - -#include "NOD_socket.h" - -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 = (bNodeSocketValueFloat *)sock->default_value; - dval->value = stemp->val1; - dval->min = stemp->min; - dval->max = stemp->max; - break; - } - case SOCK_INT: { - bNodeSocketValueInt *dval = (bNodeSocketValueInt *)sock->default_value; - dval->value = (int)stemp->val1; - dval->min = (int)stemp->min; - dval->max = (int)stemp->max; - break; - } - case SOCK_BOOLEAN: { - bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)sock->default_value; - dval->value = (int)stemp->val1; - break; - } - case SOCK_VECTOR: { - bNodeSocketValueVector *dval = (bNodeSocketValueVector *)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 = (bNodeSocketValueRGBA *)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) -{ - bNodeSocket *sock; - - for (sock = (bNodeSocket *)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->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) -{ - 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 = (bNodeSocket *)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); - } - } -} - -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 = (bNodeSocketValueFloat *)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 = (bNodeSocketValueInt *)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 = (bNodeSocketValueBoolean *)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 = (bNodeSocketValueVector *)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 = (bNodeSocketValueRGBA *)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 = (bNodeSocketValueString *)MEM_callocN( - sizeof(bNodeSocketValueString), "node socket value string"); - dval->subtype = subtype; - dval->value[0] = '\0'; - - sock->default_value = dval; - break; - } - case SOCK_OBJECT: { - bNodeSocketValueObject *dval = (bNodeSocketValueObject *)MEM_callocN( - sizeof(bNodeSocketValueObject), "node socket value object"); - dval->value = NULL; - - sock->default_value = dval; - break; - } - case SOCK_IMAGE: { - bNodeSocketValueImage *dval = (bNodeSocketValueImage *)MEM_callocN( - sizeof(bNodeSocketValueImage), "node socket value image"); - dval->value = NULL; - - 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); - - /* use label instead of name if it has been set */ - if (from->label[0] != '\0') { - BLI_strncpy(to->name, from->label, NODE_MAXSTR); - } - - switch (from->typeinfo->type) { - case SOCK_FLOAT: { - bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)to->default_value; - bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_INT: { - bNodeSocketValueInt *toval = (bNodeSocketValueInt *)to->default_value; - bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_BOOLEAN: { - bNodeSocketValueBoolean *toval = (bNodeSocketValueBoolean *)to->default_value; - bNodeSocketValueBoolean *fromval = (bNodeSocketValueBoolean *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_VECTOR: { - bNodeSocketValueVector *toval = (bNodeSocketValueVector *)to->default_value; - bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_RGBA: { - bNodeSocketValueRGBA *toval = (bNodeSocketValueRGBA *)to->default_value; - bNodeSocketValueRGBA *fromval = (bNodeSocketValueRGBA *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_STRING: { - bNodeSocketValueString *toval = (bNodeSocketValueString *)to->default_value; - bNodeSocketValueString *fromval = (bNodeSocketValueString *)from->default_value; - *toval = *fromval; - break; - } - case SOCK_OBJECT: { - bNodeSocketValueObject *toval = (bNodeSocketValueObject *)to->default_value; - bNodeSocketValueObject *fromval = (bNodeSocketValueObject *)from->default_value; - *toval = *fromval; - id_us_plus(&toval->value->id); - break; - } - case SOCK_IMAGE: { - bNodeSocketValueImage *toval = (bNodeSocketValueImage *)to->default_value; - bNodeSocketValueImage *fromval = (bNodeSocketValueImage *)from->default_value; - *toval = *fromval; - id_us_plus(&toval->value->id); - 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)) -{ - /* 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)) -{ - /* 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 = (bNodeSocketValueFloat *)sock->default_value; - bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)stemp->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_INT: { - bNodeSocketValueInt *toval = (bNodeSocketValueInt *)sock->default_value; - bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)stemp->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_VECTOR: { - bNodeSocketValueVector *toval = (bNodeSocketValueVector *)sock->default_value; - bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)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) -{ - /* 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 *); - - const char *socket_idname = nodeStaticSocketType(type, subtype); - const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); - bNodeSocketType *stype; - StructRNA *srna; - - stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); - stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; - 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 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; - - /* 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->use_link_limits_of_type = true; - stype->input_link_limit = 1; - stype->output_link_limit = 0xFFF; - - return stype; -} - -static bNodeSocketType *make_socket_type_virtual(void) -{ - extern void ED_init_node_socket_type_virtual(bNodeSocketType *); - - const char *socket_idname = "NodeSocketVirtual"; - bNodeSocketType *stype; - StructRNA *srna; - - stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); - stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; - 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); - - /* extra type info for standard socket types */ - stype->type = SOCK_CUSTOM; - - ED_init_node_socket_type_virtual(stype); - - stype->use_link_limits_of_type = true; - stype->input_link_limit = 1; - stype->output_link_limit = 1; - - return stype; -} - -static bNodeSocketType *make_socket_type_effector(int type) -{ - bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); - stype->input_link_limit = 0xFFF; - return stype; -} - -static bNodeSocketType *make_socket_type_control_flow(int type) -{ - bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); - return stype; -} - -void register_standard_node_socket_types(void) -{ - /* 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_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_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_STRING, PROP_NONE)); - - nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); - - nodeRegisterSocketType(make_standard_socket_type(SOCK_OBJECT, PROP_NONE)); - - nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE)); - - nodeRegisterSocketType(make_socket_type_effector(SOCK_EMITTERS)); - nodeRegisterSocketType(make_socket_type_effector(SOCK_EVENTS)); - nodeRegisterSocketType(make_socket_type_effector(SOCK_FORCES)); - - nodeRegisterSocketType(make_socket_type_control_flow(SOCK_CONTROL_FLOW)); - - nodeRegisterSocketType(make_socket_type_virtual()); -} diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc new file mode 100644 index 00000000000..053e4e138c8 --- /dev/null +++ b/source/blender/nodes/intern/node_socket.cc @@ -0,0 +1,557 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup nodes + */ + +#include + +#include "DNA_node_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_lib_id.h" +#include "BKE_node.h" + +#include "RNA_access.h" +#include "RNA_types.h" + +#include "MEM_guardedalloc.h" + +#include "NOD_socket.h" + +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 = (bNodeSocketValueFloat *)sock->default_value; + dval->value = stemp->val1; + dval->min = stemp->min; + dval->max = stemp->max; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *dval = (bNodeSocketValueInt *)sock->default_value; + dval->value = (int)stemp->val1; + dval->min = (int)stemp->min; + dval->max = (int)stemp->max; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *dval = (bNodeSocketValueBoolean *)sock->default_value; + dval->value = (int)stemp->val1; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *dval = (bNodeSocketValueVector *)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 = (bNodeSocketValueRGBA *)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) +{ + bNodeSocket *sock; + + for (sock = (bNodeSocket *)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->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) +{ + 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 = (bNodeSocket *)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); + } + } +} + +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 = (bNodeSocketValueFloat *)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 = (bNodeSocketValueInt *)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 = (bNodeSocketValueBoolean *)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 = (bNodeSocketValueVector *)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 = (bNodeSocketValueRGBA *)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 = (bNodeSocketValueString *)MEM_callocN( + sizeof(bNodeSocketValueString), "node socket value string"); + dval->subtype = subtype; + dval->value[0] = '\0'; + + sock->default_value = dval; + break; + } + case SOCK_OBJECT: { + bNodeSocketValueObject *dval = (bNodeSocketValueObject *)MEM_callocN( + sizeof(bNodeSocketValueObject), "node socket value object"); + dval->value = NULL; + + sock->default_value = dval; + break; + } + case SOCK_IMAGE: { + bNodeSocketValueImage *dval = (bNodeSocketValueImage *)MEM_callocN( + sizeof(bNodeSocketValueImage), "node socket value image"); + dval->value = NULL; + + 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); + + /* use label instead of name if it has been set */ + if (from->label[0] != '\0') { + BLI_strncpy(to->name, from->label, NODE_MAXSTR); + } + + switch (from->typeinfo->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)to->default_value; + bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = (bNodeSocketValueInt *)to->default_value; + bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *toval = (bNodeSocketValueBoolean *)to->default_value; + bNodeSocketValueBoolean *fromval = (bNodeSocketValueBoolean *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = (bNodeSocketValueVector *)to->default_value; + bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_RGBA: { + bNodeSocketValueRGBA *toval = (bNodeSocketValueRGBA *)to->default_value; + bNodeSocketValueRGBA *fromval = (bNodeSocketValueRGBA *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_STRING: { + bNodeSocketValueString *toval = (bNodeSocketValueString *)to->default_value; + bNodeSocketValueString *fromval = (bNodeSocketValueString *)from->default_value; + *toval = *fromval; + break; + } + case SOCK_OBJECT: { + bNodeSocketValueObject *toval = (bNodeSocketValueObject *)to->default_value; + bNodeSocketValueObject *fromval = (bNodeSocketValueObject *)from->default_value; + *toval = *fromval; + id_us_plus(&toval->value->id); + break; + } + case SOCK_IMAGE: { + bNodeSocketValueImage *toval = (bNodeSocketValueImage *)to->default_value; + bNodeSocketValueImage *fromval = (bNodeSocketValueImage *)from->default_value; + *toval = *fromval; + id_us_plus(&toval->value->id); + 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)) +{ + /* 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)) +{ + /* 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 = (bNodeSocketValueFloat *)sock->default_value; + bNodeSocketValueFloat *fromval = (bNodeSocketValueFloat *)stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = (bNodeSocketValueInt *)sock->default_value; + bNodeSocketValueInt *fromval = (bNodeSocketValueInt *)stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = (bNodeSocketValueVector *)sock->default_value; + bNodeSocketValueVector *fromval = (bNodeSocketValueVector *)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) +{ + /* initialize settings */ + stemp->type = stemp->typeinfo->type; + node_socket_copy_default_value(stemp, sock); +} + +extern "C" void ED_init_standard_node_socket_type(bNodeSocketType *); + +static bNodeSocketType *make_standard_socket_type(int type, int subtype) +{ + const char *socket_idname = nodeStaticSocketType(type, subtype); + const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype); + bNodeSocketType *stype; + StructRNA *srna; + + stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); + stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; + 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 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; + + /* 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->use_link_limits_of_type = true; + stype->input_link_limit = 1; + stype->output_link_limit = 0xFFF; + + return stype; +} + +extern "C" void ED_init_node_socket_type_virtual(bNodeSocketType *); + +static bNodeSocketType *make_socket_type_virtual(void) +{ + const char *socket_idname = "NodeSocketVirtual"; + bNodeSocketType *stype; + StructRNA *srna; + + stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type"); + stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN; + 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); + + /* extra type info for standard socket types */ + stype->type = SOCK_CUSTOM; + + ED_init_node_socket_type_virtual(stype); + + stype->use_link_limits_of_type = true; + stype->input_link_limit = 1; + stype->output_link_limit = 1; + + return stype; +} + +static bNodeSocketType *make_socket_type_effector(int type) +{ + bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); + stype->input_link_limit = 0xFFF; + return stype; +} + +static bNodeSocketType *make_socket_type_control_flow(int type) +{ + bNodeSocketType *stype = make_standard_socket_type(type, PROP_NONE); + return stype; +} + +void register_standard_node_socket_types(void) +{ + /* 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_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_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_STRING, PROP_NONE)); + + nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE)); + + nodeRegisterSocketType(make_standard_socket_type(SOCK_OBJECT, PROP_NONE)); + + nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE)); + + nodeRegisterSocketType(make_socket_type_effector(SOCK_EMITTERS)); + nodeRegisterSocketType(make_socket_type_effector(SOCK_EVENTS)); + nodeRegisterSocketType(make_socket_type_effector(SOCK_FORCES)); + + nodeRegisterSocketType(make_socket_type_control_flow(SOCK_CONTROL_FLOW)); + + nodeRegisterSocketType(make_socket_type_virtual()); +} -- cgit v1.2.3