Index: source/blender/blenkernel/BKE_node.h =================================================================== --- source/blender/blenkernel/BKE_node.h (revision 16649) +++ source/blender/blenkernel/BKE_node.h (working copy) @@ -62,11 +62,11 @@ float val1, val2, val3, val4; /* default alloc value for inputs */ float min, max; /* default range for inputs */ + short flag, pad[3]; /* after this line is used internal only */ struct bNodeSocket *sock; /* used during verify_types */ struct bNodeSocket *internsock; /* group nodes, the internal socket counterpart */ int own_index; /* verify group nodes */ - } bNodeSocketType; typedef struct bNodeType { Index: source/blender/blenkernel/intern/node.c =================================================================== --- source/blender/blenkernel/intern/node.c (revision 16649) +++ source/blender/blenkernel/intern/node.c (working copy) @@ -127,6 +127,7 @@ } node->typeinfo= stype; node->typeinfo->initfunc(node); + } else { node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL); } @@ -171,6 +172,7 @@ sock->ns.vec[3]= stype->val4; sock->ns.min= stype->min; sock->ns.max= stype->max; + sock->flag = stype->flag; if(lb) BLI_addtail(lb, sock); Index: source/blender/makesdna/DNA_node_types.h =================================================================== --- source/blender/makesdna/DNA_node_types.h (revision 16649) +++ source/blender/makesdna/DNA_node_types.h (working copy) @@ -261,6 +261,11 @@ float fstop, maxblur, bthresh, scale; } NodeDefocus; +/* qdn: value node */ +typedef struct NodeValue { + float min, max; +} NodeValue; + typedef struct NodeScriptDict { void *dict; /* for PyObject *dict */ void *node; /* for BPy_Node *node */ Index: source/blender/src/drawnode.c =================================================================== --- source/blender/src/drawnode.c (revision 16649) +++ source/blender/src/drawnode.c (working copy) @@ -167,6 +167,28 @@ /* ************** Socket callbacks *********** */ +static void node_value_cb(void *ntree_v, void *node_v) +{ + + bNode *node= node_v; + bNodeSocket *nsock; + + for(nsock= node->inputs.first; nsock; nsock= nsock->next) { + if(!node->custom1 && (strcmp(nsock->name, "Seed") == 0) ){ + nsock->flag=(nsock->flag | SOCK_UNAVAIL); +} + + else { + nsock->flag=(nsock->flag ^ SOCK_UNAVAIL); + + + } + } + + + +} + static void socket_vector_menu_cb(void *node_v, void *ntree_v) { if(node_v && ntree_v) { @@ -292,17 +314,37 @@ return 19; } + + static int node_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) { if(block) { - bNodeSocket *sock= node->outputs.first; /* first socket stores value */ + NodeValue *value_data= node->storage; + bNodeSocket *sock= node->outputs.first; + uiBut *rbt; + + + rbt=uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Random", + butr->xmin, butr->ymin+40, butr->xmax-butr->xmin, 20, + &node->custom1, 0, 0, 0, 0, "Use random value."); + uiButSetFunc(rbt, node_value_cb, ntree, node); - uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", - butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, - sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, ""); - + if(!node->custom1) { + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + sock->ns.vec, sock->ns.min, sock->ns.max, 10, 2, ""); + + } else { + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Min", + butr->xmin, butr->ymin+20, butr->xmax-butr->xmin, 20, + &value_data->min,0, 1, 10, 2, "Minimum random value."); + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Max", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + &value_data->max,0, 1,10,2, "Maximum random value."); + } } - return 20; + return 60; } static int node_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) Index: source/blender/nodes/intern/SHD_nodes/SHD_value.c =================================================================== --- source/blender/nodes/intern/SHD_nodes/SHD_value.c (revision 16649) +++ source/blender/nodes/intern/SHD_nodes/SHD_value.c (working copy) @@ -35,35 +35,70 @@ { -1, 0, "" } }; +static bNodeSocketType sh_node_value_in[]= { + { SOCK_VALUE, 1, "Seed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,SOCK_UNAVAIL}, + { -1, 0, "" } +}; + static void node_shader_exec_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock= node->outputs.first; + bNodeSocket *sock = node->outputs.first; + NodeValue *value_data = node->storage; + float rt, seed, rng; + unsigned int max_int = ~0; + static float lastval; - out[0]->vec[0]= sock->ns.vec[0]; + if(!node->custom1) { + rt = sock->ns.vec[0]; + } else { + /* random value */ + if(!in[0]->hasinput) { + BLI_srand(fabs(lastval * max_int)); + seed = BLI_frand() * BLI_frand(); + } else { + seed = in[0]->vec[0]; + } + + BLI_srand(fabs(seed * max_int)); + rng = fabs(value_data->max - value_data->min); + lastval = rt = value_data->min + BLI_frand() * rng; + } + + out[0]->vec[0] = rt; } static int gpu_shader_value(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) { - bNodeSocket *sock= node->outputs.first; + bNodeSocket *sock = node->outputs.first; GPUNodeLink *vec = GPU_uniform(sock->ns.vec); + /* FIXME: doesn't take random value in count? */ + return GPU_stack_link(mat, "set_value", in, out, vec); } +static void sh_node_composit_init_value(bNode* node) +{ + NodeValue *ndg = MEM_callocN(sizeof(NodeValue), "sh node value data"); + ndg->min = 0; + ndg->max = 1; + node->storage = ndg; +} + bNodeType sh_node_value= { /* *next,*prev */ NULL, NULL, /* type code */ SH_NODE_VALUE, /* name */ "Value", - /* width+range */ 80, 50, 120, + /* width+range */ 100, 40, 120, /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, - /* input sock */ NULL, + /* input sock */ sh_node_value_in, /* output sock */ sh_node_value_out, - /* storage */ "", + /* storage */ "NodeValue", /* execfunc */ node_shader_exec_value, /* butfunc */ NULL, - /* initfunc */ NULL, - /* freestoragefunc */ NULL, - /* copystoragefunc */ NULL, + /* initfunc */ sh_node_composit_init_value, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, /* id */ NULL, NULL, NULL, /* gpufunc */ gpu_shader_value Index: source/blender/nodes/intern/CMP_nodes/CMP_value.c =================================================================== --- source/blender/nodes/intern/CMP_nodes/CMP_value.c (revision 16649) +++ source/blender/nodes/intern/CMP_nodes/CMP_value.c (working copy) @@ -35,27 +35,61 @@ { -1, 0, "" } }; +static bNodeSocketType cmp_node_value_in[]= { + { SOCK_VALUE, 1, "Seed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,SOCK_UNAVAIL}, + { -1, 0, "" } +}; + static void node_composit_exec_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { - bNodeSocket *sock= node->outputs.first; + bNodeSocket *sock= node->outputs.first; + NodeValue *value_data = node->storage; + float rt, seed, rng; + unsigned int max_int = ~0; + static float lastval; - out[0]->vec[0]= sock->ns.vec[0]; + if(!node->custom1) { + rt = sock->ns.vec[0]; + } else { + /* random value */ + if(!in[0]->hasinput) { + BLI_srand(fabs(lastval * max_int)); + seed = BLI_frand() * BLI_frand(); + } else { + seed = in[0]->vec[0]; + } + + BLI_srand(fabs(seed * max_int)); + rng = fabs(value_data->max - value_data->min); + lastval = rt = value_data->min + BLI_frand() * rng; + } + + out[0]->vec[0] = rt; } +static void cmp_node_composit_init_value(bNode* node) +{ + NodeValue *ndg = MEM_callocN(sizeof(NodeValue), "node value data"); + ndg->min = 0; + ndg->max = 1; + node->storage = ndg; + +} + bNodeType cmp_node_value= { /* *next,*prev */ NULL, NULL, /* type code */ CMP_NODE_VALUE, /* name */ "Value", - /* width+range */ 80, 40, 120, + /* width+range */ 100, 40, 120, /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, - /* input sock */ NULL, + /* input sock */ cmp_node_value_in, /* output sock */ cmp_node_value_out, - /* storage */ "", + /* storage */ "NodeValue", /* execfunc */ node_composit_exec_value, /* butfunc */ NULL, - /* initfunc */ NULL, - /* freestoragefunc */ NULL, - /* copystoragefunc */ NULL, + /* initfunc */ cmp_node_composit_init_value, + /* freestoragefunc */ node_free_standard_storage, + /* copystoragefunc */ node_copy_standard_storage, /* id */ NULL };