Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-01-20 17:27:54 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-01-20 17:27:54 +0400
commit0b412e41368824f47cdd6643c86e4acaf28728e5 (patch)
tree04e346890ada996bddf9399cc6c679a919213fc3
parent5c6413f69527e76b608f8063d99b52f3f5579d0b (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.
-rw-r--r--source/blender/blenkernel/intern/node.c39
-rw-r--r--source/blender/editors/space_node/node_templates.c11
-rw-r--r--source/blender/nodes/NOD_socket.h33
-rw-r--r--source/blender/nodes/intern/node_common.c195
-rw-r--r--source/blender/nodes/intern/node_socket.c354
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;
}