diff options
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 39 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_templates.c | 11 | ||||
-rw-r--r-- | source/blender/nodes/NOD_socket.h | 33 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_common.c | 195 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.c | 354 |
5 files changed, 295 insertions, 337 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a2d7d9b502c..96ee2bd0349 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -159,7 +159,6 @@ void ntreeInitTypes(bNodeTree *ntree) static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char *name, int type) { - bNodeSocketType *stype= ntreeGetSocketType(type); bNodeSocket *sock; sock= MEM_callocN(sizeof(bNodeSocket), "sock"); @@ -169,8 +168,8 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char sock->type= type; sock->storage = NULL; - if (stype->value_structsize > 0) - sock->default_value = MEM_callocN(stype->value_structsize, "default socket value"); + sock->default_value = node_socket_make_default_value(type); + node_socket_init_default_value(type, sock->default_value); return sock; } @@ -216,8 +215,7 @@ void nodeRemoveSocket(bNodeTree *ntree, bNode *node, bNodeSocket *sock) BLI_remlink(&node->inputs, sock); BLI_remlink(&node->outputs, sock); - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); node->update |= NODE_UPDATE; @@ -236,13 +234,10 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node) } for (sock=node->inputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->inputs); for (sock=node->outputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); - + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&node->outputs); node->update |= NODE_UPDATE; @@ -396,7 +391,8 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) oldsock->new_sock= sock; sock->stack_index= 0; - sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + sock->default_value = node_socket_make_default_value(oldsock->type); + node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); /* XXX some compositor node (e.g. image, render layers) still store * some persistent buffer data here, need to clear this to avoid dangling pointers. @@ -410,7 +406,8 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) oldsock->new_sock= sock; sock->stack_index= 0; - sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL); + sock->default_value = node_socket_make_default_value(oldsock->type); + node_socket_copy_default_value(oldsock->type, sock->default_value, oldsock->default_value); /* XXX some compositor node (e.g. image, render layers) still store * some persistent buffer data here, need to clear this to avoid dangling pointers. @@ -658,13 +655,15 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) for(gsock= newtree->inputs.first, oldgsock= ntree->inputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); - gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); + gsock->default_value = node_socket_make_default_value(oldgsock->type); + node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); } BLI_duplicatelist(&newtree->outputs, &ntree->outputs); for(gsock= newtree->outputs.first, oldgsock= ntree->outputs.first; gsock; gsock=gsock->next, oldgsock=oldgsock->next) { oldgsock->new_sock= gsock; gsock->groupsock = (oldgsock->groupsock ? oldgsock->groupsock->new_sock : NULL); - gsock->default_value = (oldgsock->default_value ? MEM_dupallocN(oldgsock->default_value) : NULL); + gsock->default_value = node_socket_make_default_value(oldgsock->type); + node_socket_copy_default_value(oldgsock->type, gsock->default_value, oldgsock->default_value); } /* copy links */ @@ -863,14 +862,12 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) for (sock=node->inputs.first; sock; sock = nextsock) { nextsock = sock->next; - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); } for (sock=node->outputs.first; sock; sock = nextsock) { nextsock = sock->next; - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); MEM_freeN(sock); } @@ -924,12 +921,10 @@ void ntreeFreeTree(bNodeTree *ntree) } for (sock=ntree->inputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->inputs); for (sock=ntree->outputs.first; sock; sock=sock->next) - if (sock->default_value) - MEM_freeN(sock->default_value); + node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->outputs); } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index a733d45c20b..8d82dd3fb53 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -49,6 +49,8 @@ #include "RNA_access.h" +#include "NOD_socket.h" + #include "WM_api.h" #include "WM_types.h" @@ -205,12 +207,9 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t nodeRemLink(ntree, link); } - if(sock_prev->default_value) { - if(sock_from->default_value) - MEM_freeN(sock_from->default_value); - - sock_from->default_value = MEM_dupallocN(sock_prev->default_value); - } + node_socket_free_default_value(sock_from->type, sock_from->default_value); + sock_from->default_value = node_socket_make_default_value(sock_from->type); + node_socket_copy_default_value(sock_from->type, sock_from->default_value, sock_prev->default_value); } } } diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h index 6a6413d508f..fb3946bae6c 100644 --- a/source/blender/nodes/NOD_socket.h +++ b/source/blender/nodes/NOD_socket.h @@ -47,26 +47,19 @@ struct bNodeStack; void node_socket_type_init(struct bNodeSocketType *types[]); -struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, int value, int min, int max); -struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float value, float min, float max); -struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value); -struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, float x, float y, float z, float min, float max); -struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, float r, float g, float b, float a); -struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name); -struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name); - -struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); -struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name); +void *node_socket_make_default_value(int type); +void node_socket_free_default_value(int type, void *default_value); +void node_socket_init_default_value(int type, void *default_value); +void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value); +void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value); + +void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max); +void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max); +void node_socket_set_default_value_boolean(void *default_value, char value); +void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max); +void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a); +void node_socket_set_default_value_shader(void *default_value); +void node_socket_set_default_value_mesh(void *default_value); struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp); struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp); diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 5a6cebb51ce..e5571b19614 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -100,8 +100,8 @@ bNodeSocket *node_group_add_extern_socket(bNodeTree *UNUSED(ntree), ListBase *lb sock->groupsock = gsock; sock->limit = (in_out==SOCK_IN ? 1 : 0xFFF); - if (gsock->default_value) - sock->default_value = MEM_dupallocN(gsock->default_value); + sock->default_value = node_socket_make_default_value(sock->type); + node_socket_copy_default_value(sock->type, sock->default_value, gsock->default_value); if(lb) BLI_addtail(lb, sock); @@ -247,177 +247,6 @@ bNode *node_group_make_from_selected(bNodeTree *ntree) return gnode; } -/* XXX This is a makeshift function to have useful initial group socket values. - * In the end this should be implemented by a flexible socket data conversion system, - * which is yet to be implemented. The idea is that beside default standard conversions, - * such as int-to-float, it should be possible to quickly select a conversion method or - * a chain of conversions for each input, whenever there is more than one option. - * E.g. a vector-to-float conversion could use either of the x/y/z components or - * the vector length. - * - * In the interface this could be implemented by a pseudo-script textbox on linked inputs, - * with quick selection from a predefined list of conversion options. Some Examples: - * - vector component 'z' (vector->float): "z" - * - greyscale color (float->color): "grey" - * - color luminance (color->float): "lum" - * - matrix column 2 length (matrix->vector->float): "col[1].len" - * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y" - * - * The actual conversion is then done by a series of conversion functions, - * which are defined in the socket type structs. - */ -static void convert_socket_value(bNodeSocket *from, bNodeSocket *to) -{ - /* XXX only one of these pointers is valid! just putting them here for convenience */ - bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; - bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; - bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; - bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; - bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; - - bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; - bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; - bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; - bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; - bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; - - switch (from->type) { - case SOCK_FLOAT: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromfloat->value; - break; - case SOCK_INT: - toint->value = (int)fromfloat->value; - break; - case SOCK_BOOLEAN: - tobool->value = (fromfloat->value > 0.0f); - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; - break; - } - break; - case SOCK_INT: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = (float)fromint->value; - break; - case SOCK_INT: - toint->value = fromint->value; - break; - case SOCK_BOOLEAN: - tobool->value = (fromint->value > 0); - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; - break; - } - break; - case SOCK_BOOLEAN: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = (float)frombool->value; - break; - case SOCK_INT: - toint->value = (int)frombool->value; - break; - case SOCK_BOOLEAN: - tobool->value = frombool->value; - break; - case SOCK_VECTOR: - tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; - break; - case SOCK_RGBA: - torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; - break; - } - break; - case SOCK_VECTOR: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromvector->value[0]; - break; - case SOCK_INT: - toint->value = (int)fromvector->value[0]; - break; - case SOCK_BOOLEAN: - tobool->value = (fromvector->value[0] > 0.0f); - break; - case SOCK_VECTOR: - copy_v3_v3(tovector->value, fromvector->value); - break; - case SOCK_RGBA: - copy_v3_v3(torgba->value, fromvector->value); - torgba->value[3] = 1.0f; - break; - } - break; - case SOCK_RGBA: - switch (to->type) { - case SOCK_FLOAT: - tofloat->value = fromrgba->value[0]; - break; - case SOCK_INT: - toint->value = (int)fromrgba->value[0]; - break; - case SOCK_BOOLEAN: - tobool->value = (fromrgba->value[0] > 0.0f); - break; - case SOCK_VECTOR: - copy_v3_v3(tovector->value, fromrgba->value); - break; - case SOCK_RGBA: - copy_v4_v4(torgba->value, fromrgba->value); - break; - } - break; - } -} - -static void copy_socket_value(bNodeSocket *from, bNodeSocket *to) -{ - /* XXX only one of these pointers is valid! just putting them here for convenience */ - bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from->default_value; - bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from->default_value; - bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from->default_value; - bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from->default_value; - bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from->default_value; - - bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to->default_value; - bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to->default_value; - bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to->default_value; - bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to->default_value; - bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to->default_value; - - if (from->type != to->type) - return; - - switch (from->type) { - case SOCK_FLOAT: - *tofloat = *fromfloat; - break; - case SOCK_INT: - *toint = *fromint; - break; - case SOCK_BOOLEAN: - *tobool = *frombool; - break; - case SOCK_VECTOR: - *tovector = *fromvector; - break; - case SOCK_RGBA: - *torgba = *fromrgba; - break; - } -} - /* returns 1 if its OK */ int node_group_ungroup(bNodeTree *ntree, bNode *gnode) { @@ -489,7 +318,7 @@ int node_group_ungroup(bNodeTree *ntree, bNode *gnode) } else { /* copy the default input value from the group socket default to the external socket */ - convert_socket_value(gsock, link->tosock); + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value); } } } @@ -517,7 +346,7 @@ int node_group_ungroup(bNodeTree *ntree, bNode *gnode) } else { /* copy the default input value from the group node socket default to the internal socket */ - convert_socket_value(insock, link->tosock); + node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value); nodeRemLink(wgroup, link); } } @@ -600,7 +429,7 @@ bNodeSocket *node_group_expose_socket(bNodeTree *ngroup, bNodeSocket *sock, int bNodeSocket *gsock= node_group_add_socket(ngroup, sock->name, sock->type, in_out); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); return gsock; } @@ -616,7 +445,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup) gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); sock->link = nodeAddLink(ngroup, NULL, gsock, node, sock); } @@ -626,7 +455,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup) gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); /* initialize the default value. */ - copy_socket_value(sock, gsock); + node_socket_copy_default_value(gsock->type, gsock->default_value, sock->default_value); gsock->link = nodeAddLink(ngroup, node, sock, NULL, gsock); } @@ -832,11 +661,12 @@ bNodeTemplate node_forloop_template(bNode *node) void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - /* bNodeSocket *sock; */ /* UNUSED */ + bNodeSocket *sock; node->id = (ID*)ntemp->ngroup; - /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); + sock = nodeAddSocket(ntree, node, SOCK_IN, "Iterations", SOCK_FLOAT); + node_socket_set_default_value_float(sock->default_value, PROP_UNSIGNED, 1, 0, 10000); /* NB: group socket input/output roles are inverted internally! * Group "inputs" work as outputs in links and vice versa. @@ -938,11 +768,12 @@ void node_loop_update_tree(bNodeTree *ngroup) void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - /* bNodeSocket *sock; */ /* UNUSED */ + bNodeSocket *sock; node->id = (ID*)ntemp->ngroup; - /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); + sock = nodeAddSocket(ntree, node, SOCK_IN, "Condition", SOCK_FLOAT); + node_socket_set_default_value_float(sock->default_value, PROP_NONE, 1, 0, 1); /* max iterations */ node->custom1 = 10000; diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 9381eff30dd..8f468a574a1 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -29,6 +29,7 @@ * \ingroup nodes */ +#include <limits.h> #include "DNA_node_types.h" @@ -172,171 +173,310 @@ void node_socket_type_init(bNodeSocketType *types[]) #undef INIT_TYPE } -struct bNodeSocket *nodeAddInputInt(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - int value, int min, int max) +void *node_socket_make_default_value(int type) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_INT); - bNodeSocketValueInt *dval= (bNodeSocketValueInt*)sock->default_value; - dval->subtype = subtype; - dval->value = value; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputInt(struct bNodeTree *ntree, struct bNode *node, const char *name) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_INT); - return sock; + /* XXX currently just allocates from stype->structsize. + * it might become necessary to do more complex allocations for later types. + */ + bNodeSocketType *stype = ntreeGetSocketType(type); + if (stype->value_structsize > 0) { + void *default_value = MEM_callocN(stype->value_structsize, "default socket value"); + return default_value; + } + else + return NULL; } -struct bNodeSocket *nodeAddInputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - float value, float min, float max) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_FLOAT); - bNodeSocketValueFloat *dval= (bNodeSocketValueFloat*)sock->default_value; - dval->subtype = subtype; - dval->value = value; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputFloat(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_free_default_value(int UNUSED(type), void *default_value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_FLOAT); - return sock; + /* XXX can just free the pointee for all current socket types. */ + MEM_freeN(default_value); } -struct bNodeSocket *nodeAddInputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name, char value) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_BOOLEAN); - bNodeSocketValueBoolean *dval= (bNodeSocketValueBoolean*)sock->default_value; - dval->value = value; - return sock; -} -struct bNodeSocket *nodeAddOutputBoolean(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_init_default_value(int type, void *default_value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_BOOLEAN); - return sock; + switch (type) { + case SOCK_FLOAT: + node_socket_set_default_value_float(default_value, PROP_NONE, 0.0f, -FLT_MAX, FLT_MAX); + break; + case SOCK_INT: + node_socket_set_default_value_int(default_value, PROP_NONE, 0, INT_MIN, INT_MAX); + break; + case SOCK_BOOLEAN: + node_socket_set_default_value_boolean(default_value, FALSE); + break; + case SOCK_VECTOR: + node_socket_set_default_value_vector(default_value, PROP_NONE, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX); + break; + case SOCK_RGBA: + node_socket_set_default_value_rgba(default_value, 0.0f, 0.0f, 0.0f, 1.0f); + break; + case SOCK_SHADER: + node_socket_set_default_value_shader(default_value); + break; + case SOCK_MESH: + node_socket_set_default_value_mesh(default_value); + break; + } } -struct bNodeSocket *nodeAddInputVector(struct bNodeTree *ntree, struct bNode *node, const char *name, PropertySubType subtype, - float x, float y, float z, float min, float max) +void node_socket_set_default_value_int(void *default_value, PropertySubType subtype, int value, int min, int max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_VECTOR); - bNodeSocketValueVector *dval= (bNodeSocketValueVector*)sock->default_value; - dval->subtype = subtype; - dval->value[0] = x; - dval->value[1] = y; - dval->value[2] = z; - dval->min = min; - dval->max = max; - return sock; -} -struct bNodeSocket *nodeAddOutputVector(struct bNodeTree *ntree, struct bNode *node, const char *name) -{ - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_VECTOR); - return sock; + bNodeSocketValueInt *val = default_value; + val->subtype = subtype; + val->value = value; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddInputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name, - float r, float g, float b, float a) +void node_socket_set_default_value_float(void *default_value, PropertySubType subtype, float value, float min, float max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_RGBA); - bNodeSocketValueRGBA *dval= (bNodeSocketValueRGBA*)sock->default_value; - dval->value[0] = r; - dval->value[1] = g; - dval->value[2] = b; - dval->value[3] = a; - return sock; + bNodeSocketValueFloat *val = default_value; + val->subtype = subtype; + val->value = value; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddOutputRGBA(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_boolean(void *default_value, char value) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_RGBA); - return sock; + bNodeSocketValueBoolean *val = default_value; + val->value = value; } -struct bNodeSocket *nodeAddInputShader(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_set_default_value_vector(void *default_value, PropertySubType subtype, float x, float y, float z, float min, float max) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_SHADER); - return sock; + bNodeSocketValueVector *val = default_value; + val->subtype = subtype; + val->value[0] = x; + val->value[1] = y; + val->value[2] = z; + val->min = min; + val->max = max; } -struct bNodeSocket *nodeAddOutputShader(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_rgba(void *default_value, float r, float g, float b, float a) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_SHADER); - return sock; + bNodeSocketValueRGBA *val = default_value; + val->value[0] = r; + val->value[1] = g; + val->value[2] = b; + val->value[3] = a; } -struct bNodeSocket *nodeAddInputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) +void node_socket_set_default_value_shader(void *UNUSED(default_value)) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_IN, name, SOCK_MESH); - return sock; } -struct bNodeSocket *nodeAddOutputMesh(struct bNodeTree *ntree, struct bNode *node, const char *name) + +void node_socket_set_default_value_mesh(void *UNUSED(default_value)) { - bNodeSocket *sock= nodeAddSocket(ntree, node, SOCK_OUT, name, SOCK_MESH); - return sock; } -struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) + +void node_socket_copy_default_value(int type, void *to_default_value, void *from_default_value) { - bNodeSocket *sock; - switch (stemp->type) { - case SOCK_INT: - sock = nodeAddInputInt(ntree, node, stemp->name, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max); - break; + /* XXX only one of these pointers is valid! just putting them here for convenience */ + bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; + bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; + bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; + bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; + bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; + + bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; + bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; + bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; + bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; + bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; + + switch (type) { case SOCK_FLOAT: - sock = nodeAddInputFloat(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->min, stemp->max); + *tofloat = *fromfloat; + break; + case SOCK_INT: + *toint = *fromint; break; case SOCK_BOOLEAN: - sock = nodeAddInputBoolean(ntree, node, stemp->name, (char)stemp->val1); + *tobool = *frombool; break; case SOCK_VECTOR: - sock = nodeAddInputVector(ntree, node, stemp->name, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); + *tovector = *fromvector; break; case SOCK_RGBA: - sock = nodeAddInputRGBA(ntree, node, stemp->name, stemp->val1, stemp->val2, stemp->val3, stemp->val4); + *torgba = *fromrgba; break; - case SOCK_SHADER: - sock = nodeAddInputShader(ntree, node, stemp->name); + } +} + +/* XXX This is a makeshift function to have useful initial group socket values. + * In the end this should be implemented by a flexible socket data conversion system, + * which is yet to be implemented. The idea is that beside default standard conversions, + * such as int-to-float, it should be possible to quickly select a conversion method or + * a chain of conversions for each input, whenever there is more than one option. + * E.g. a vector-to-float conversion could use either of the x/y/z components or + * the vector length. + * + * In the interface this could be implemented by a pseudo-script textbox on linked inputs, + * with quick selection from a predefined list of conversion options. Some Examples: + * - vector component 'z' (vector->float): "z" + * - greyscale color (float->color): "grey" + * - color luminance (color->float): "lum" + * - matrix column 2 length (matrix->vector->float): "col[1].len" + * - mesh vertex coordinate 'y' (mesh->vertex->vector->float): "vertex.co.y" + * + * The actual conversion is then done by a series of conversion functions, + * which are defined in the socket type structs. + */ +void node_socket_convert_default_value(int to_type, void *to_default_value, int from_type, void *from_default_value) +{ + /* XXX only one of these pointers is valid! just putting them here for convenience */ + bNodeSocketValueFloat *fromfloat= (bNodeSocketValueFloat*)from_default_value; + bNodeSocketValueInt *fromint= (bNodeSocketValueInt*)from_default_value; + bNodeSocketValueBoolean *frombool= (bNodeSocketValueBoolean*)from_default_value; + bNodeSocketValueVector *fromvector= (bNodeSocketValueVector*)from_default_value; + bNodeSocketValueRGBA *fromrgba= (bNodeSocketValueRGBA*)from_default_value; + + bNodeSocketValueFloat *tofloat= (bNodeSocketValueFloat*)to_default_value; + bNodeSocketValueInt *toint= (bNodeSocketValueInt*)to_default_value; + bNodeSocketValueBoolean *tobool= (bNodeSocketValueBoolean*)to_default_value; + bNodeSocketValueVector *tovector= (bNodeSocketValueVector*)to_default_value; + bNodeSocketValueRGBA *torgba= (bNodeSocketValueRGBA*)to_default_value; + + switch (from_type) { + case SOCK_FLOAT: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromfloat->value; + break; + case SOCK_INT: + toint->value = (int)fromfloat->value; + break; + case SOCK_BOOLEAN: + tobool->value = (fromfloat->value > 0.0f); + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = fromfloat->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = fromfloat->value; + break; break; - case SOCK_MESH: - sock = nodeAddInputMesh(ntree, node, stemp->name); + } + case SOCK_INT: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = (float)fromint->value; + break; + case SOCK_INT: + toint->value = fromint->value; + break; + case SOCK_BOOLEAN: + tobool->value = (fromint->value > 0); + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)fromint->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)fromint->value; + break; + } + break; + case SOCK_BOOLEAN: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = (float)frombool->value; + break; + case SOCK_INT: + toint->value = (int)frombool->value; + break; + case SOCK_BOOLEAN: + tobool->value = frombool->value; + break; + case SOCK_VECTOR: + tovector->value[0] = tovector->value[1] = tovector->value[2] = (float)frombool->value; + break; + case SOCK_RGBA: + torgba->value[0] = torgba->value[1] = torgba->value[2] = torgba->value[3] = (float)frombool->value; + break; + } + break; + case SOCK_VECTOR: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromvector->value[0]; + break; + case SOCK_INT: + toint->value = (int)fromvector->value[0]; + break; + case SOCK_BOOLEAN: + tobool->value = (fromvector->value[0] > 0.0f); + break; + case SOCK_VECTOR: + copy_v3_v3(tovector->value, fromvector->value); + break; + case SOCK_RGBA: + copy_v3_v3(torgba->value, fromvector->value); + torgba->value[3] = 1.0f; + break; + } + break; + case SOCK_RGBA: + switch (to_type) { + case SOCK_FLOAT: + tofloat->value = fromrgba->value[0]; + break; + case SOCK_INT: + toint->value = (int)fromrgba->value[0]; + break; + case SOCK_BOOLEAN: + tobool->value = (fromrgba->value[0] > 0.0f); + break; + case SOCK_VECTOR: + copy_v3_v3(tovector->value, fromrgba->value); + break; + case SOCK_RGBA: + copy_v4_v4(torgba->value, fromrgba->value); + break; + } break; - default: - sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); } - sock->flag |= stemp->flag; - return sock; } -struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) + +struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) { - bNodeSocket *sock; + bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); + sock->flag |= stemp->flag; + switch (stemp->type) { case SOCK_INT: - sock = nodeAddOutputInt(ntree, node, stemp->name); + node_socket_set_default_value_int(sock->default_value, stemp->subtype, (int)stemp->val1, (int)stemp->min, (int)stemp->max); break; case SOCK_FLOAT: - sock = nodeAddOutputFloat(ntree, node, stemp->name); + node_socket_set_default_value_float(sock->default_value, stemp->subtype, stemp->val1, stemp->min, stemp->max); break; case SOCK_BOOLEAN: - sock = nodeAddOutputBoolean(ntree, node, stemp->name); + node_socket_set_default_value_boolean(sock->default_value, (char)stemp->val1); break; case SOCK_VECTOR: - sock = nodeAddOutputVector(ntree, node, stemp->name); + node_socket_set_default_value_vector(sock->default_value, stemp->subtype, stemp->val1, stemp->val2, stemp->val3, stemp->min, stemp->max); break; case SOCK_RGBA: - sock = nodeAddOutputRGBA(ntree, node, stemp->name); + node_socket_set_default_value_rgba(sock->default_value, stemp->val1, stemp->val2, stemp->val3, stemp->val4); break; case SOCK_SHADER: - sock = nodeAddOutputShader(ntree, node, stemp->name); + node_socket_set_default_value_shader(sock->default_value); break; case SOCK_MESH: - sock = nodeAddOutputMesh(ntree, node, stemp->name); + node_socket_set_default_value_mesh(sock->default_value); break; - default: - sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); } + + return sock; +} + +struct bNodeSocket *node_add_output_from_template(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocketTemplate *stemp) +{ + bNodeSocket *sock = nodeAddSocket(ntree, node, SOCK_OUT, stemp->name, stemp->type); return sock; } |