diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-01-20 17:27:54 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-01-20 17:27:54 +0400 |
commit | 0b412e41368824f47cdd6643c86e4acaf28728e5 (patch) | |
tree | 04e346890ada996bddf9399cc6c679a919213fc3 /source/blender | |
parent | 5c6413f69527e76b608f8063d99b52f3f5579d0b (diff) |
Cleanup of default_value handling in node sockets.
The structs stored in the anonymous void *default_value in bNodeSocket are now handled completely inside node_socket.c. All allocation/freeing/duplicating for this has been replaced by the appropriate calls to generic API functions (declared in NOD_socket.h).
This will make the default value handling more reliable for future node socket code. Group socket copying and value conversion has also been moved into the generic socket API file.
Diffstat (limited to 'source/blender')
-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; } |