It is not a well-supported feature of the primary node systems (shader, compositor, texture) in Blender. If anybody wants to create a node system that has actual use for loops, they can do so much more elegantly with Python nodes, but it does not have to be a core node type in Blender. Removing this should ease node code maintenance a bit.
/* ************** COMMON NODES *************** */
#define NODE_GROUP 2
-#define NODE_FORLOOP 3
-#define NODE_WHILELOOP 4
+#define __NODE_FORLOOP 3 /* deprecated */
+#define __NODE_WHILELOOP 4 /* deprecated */
#define NODE_FRAME 5
#define NODE_REROUTE 6
uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL);
}
-static void node_common_buts_whileloop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "max_iterations", 0, NULL, ICON_NONE);
-}
-
/* XXX Does a bounding box update by iterating over all children.
* Not ideal to do this in every draw call, but doing as transform callback doesn't work,
* since the child node totr rects are not updated properly at that point.
ntype->drawfunc = node_draw_group;
ntype->drawupdatefunc = node_update_group;
break;
- case NODE_FORLOOP:
-// ntype->uifunc= node_common_buts_group;
- ntype->drawfunc = node_draw_group;
- ntype->drawupdatefunc = node_update_group;
- break;
- case NODE_WHILELOOP:
- ntype->uifunc = node_common_buts_whileloop;
- ntype->drawfunc = node_draw_group;
- ntype->drawupdatefunc = node_update_group;
- break;
case NODE_FRAME:
ntype->drawfunc = node_draw_frame;
ntype->drawupdatefunc = node_update_frame;
case NODE_GROUP:
ntemp.ngroup = ntreeAddTree("Group", snode->treetype, ntemp.type);
break;
- case NODE_FORLOOP:
- ntemp.ngroup = ntreeAddTree("For Loop", snode->treetype, ntemp.type);
- break;
- case NODE_WHILELOOP:
- ntemp.ngroup = ntreeAddTree("While Loop", snode->treetype, ntemp.type);
- break;
default:
ntemp.ngroup = NULL;
}
/* XXX hack: negative numbers used for empty group types */
if (node_tree_has_type(ntree->type, NODE_GROUP))
uiItemV(layout, IFACE_("New Group"), 0, -NODE_GROUP);
- if (node_tree_has_type(ntree->type, NODE_FORLOOP))
- uiItemV(layout, IFACE_("New For Loop"), 0, -NODE_FORLOOP);
- if (node_tree_has_type(ntree->type, NODE_WHILELOOP))
- uiItemV(layout, IFACE_("New While Loop"), 0, -NODE_WHILELOOP);
uiItemS(layout);
for (ngroup = bmain->nodetree.first, event = 0; ngroup; ngroup = ngroup->id.next, ++event) {
/* only use group trees */
- if (ngroup->type == ntree->type && ELEM3(ngroup->nodetype, NODE_GROUP, NODE_FORLOOP, NODE_WHILELOOP)) {
+ if (ngroup->type == ntree->type && ngroup->nodetype == NODE_GROUP) {
uiItemV(layout, ngroup->id.name + 2, 0, event);
}
}
case NODE_GROUP:
return &RNA_NodeGroup;
- case NODE_FORLOOP:
- return &RNA_NodeForLoop;
- case NODE_WHILELOOP:
- return &RNA_NodeWhileLoop;
case NODE_FRAME:
return &RNA_NodeFrame;
case NODE_REROUTE:
enum
{
Category_GroupNode,
- Category_LoopNode,
Category_LayoutNode,
Category_ShaderNode,
Category_CompositorNode,
#include "rna_nodetree_types.h"
reg_node(NODE_GROUP, Category_GroupNode, "GROUP", "NodeGroup", "SpecialNode", "Group", "");
- reg_node(NODE_FORLOOP, Category_LoopNode, "FORLOOP", "NodeForLoop", "SpecialNode", "ForLoop", "");
- reg_node(NODE_WHILELOOP, Category_LoopNode, "WHILELOOP", "NodeWhileLoop", "SpecialNode", "WhileLoop", "");
reg_node(NODE_FRAME, Category_LayoutNode, "FRAME", "NodeFrame", "SpecialNode", "Frame", "");
reg_node(NODE_REROUTE, Category_LayoutNode, "REROUTE", "NodeReroute", "SpecialNode", "Reroute", "");
}
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeGroup_update");
}
-static void def_forloop(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "id");
- RNA_def_property_struct_type(prop, "NodeTree");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Node Tree", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeGroup_update");
-}
-
-static void def_whileloop(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "id");
- RNA_def_property_struct_type(prop, "NodeTree");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Node Tree", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeGroup_update");
-
- prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "custom1");
- RNA_def_property_range(prop, 0.0f, SHRT_MAX);
- RNA_def_property_ui_text(prop, "Max. Iterations", "Limit for number of iterations");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeGroup_update");
-}
-
static void def_frame(StructRNA *srna)
{
PropertyRNA *prop;
static EnumPropertyItem specific_node_type_items[] = {
{NODE_GROUP, "GROUP", ICON_NODE, "Group", ""},
- {NODE_FORLOOP, "FORLOOP", ICON_NODE, "For Loop", ""},
- {NODE_WHILELOOP, "WHILELOOP", ICON_NODE, "While Loop", ""},
{NODE_FRAME, "FRAME", ICON_NODE, "Frame", ""},
{NODE_REROUTE, "REROUTE", ICON_NODE, "Reroute", ""},
{0, NULL, 0, NULL, NULL}
#include "rna_nodetree_types.h"
define_specific_node(brna, NODE_GROUP, def_group);
- define_specific_node(brna, NODE_FORLOOP, def_forloop);
- define_specific_node(brna, NODE_WHILELOOP, def_whileloop);
define_specific_node(brna, NODE_FRAME, def_frame);
define_specific_node(brna, NODE_REROUTE, 0);
nodeRegisterType(ttype, &ntype);
}
-
-#ifdef WITH_COMPOSITOR_LEGACY
-
-/**** FOR LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-/* Move the results from the previous iteration back to the input sockets. */
-static void loop_iteration_reset(bNodeTree *ngroup, bNodeStack *gstack)
-{
- bNodeSocket *gin, *gout;
- bNodeStack *nsin, *nsout;
-
- gin = ngroup->inputs.first;
- gout = ngroup->outputs.first;
-
- while (gin && gout) {
- /* skip static (non-looping) sockets */
- while (gin && !(gin->flag & SOCK_DYNAMIC))
- gin=gin->next;
- while (gout && !(gout->flag & SOCK_DYNAMIC))
- gout=gout->next;
-
- if (gin && gout) {
- nsin = node_get_socket_stack(gstack, gin);
- nsout = node_get_socket_stack(gstack, gout);
-
- move_stack(nsin, nsout);
-
- gin=gin->next;
- gout=gout->next;
- }
- }
-}
-
-static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec *)nodedata;
- int totiterations= (int)in[0]->vec[0];
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- /* "Iteration" socket */
- sock = exec->nodetree->inputs.first;
- ns = node_get_socket_stack(exec->stack, sock);
-
- group_copy_inputs(node, in, exec->stack);
- for (iteration=0; iteration < totiterations; ++iteration) {
- /* first input contains current iteration counter */
- ns->vec[0] = (float)iteration;
-
- if (iteration > 0)
- loop_iteration_reset(exec->nodetree, exec->stack);
- ntreeExecNodes(exec, data, thread);
- group_free_internal(exec);
- }
- group_move_outputs(node, out, exec->stack);
-}
-
-void register_node_type_cmp_forloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_forloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_forloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif
-
-
-/**** WHILE LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec *)nodedata;
- int condition= (in[0]->vec[0] > 0.0f);
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- /* "Condition" socket */
- sock = exec->nodetree->outputs.first;
- ns = node_get_socket_stack(exec->stack, sock);
-
- iteration = 0;
- group_copy_inputs(node, in, exec->stack);
- while (condition && iteration < node->custom1) {
- if (iteration > 0)
- loop_iteration_reset(exec->nodetree, exec->stack);
- ntreeExecNodes(exec, data, thread);
- group_free_internal(exec);
-
-// PRINT_BUFFERS(exec);
-
- condition = (ns->vec[0] > 0.0f);
- ++iteration;
- }
- group_move_outputs(node, out, exec->stack);
-}
-
-void register_node_type_cmp_whileloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_whileloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_whileloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif
-
-#endif /* WITH_COMPOSITOR_LEGACY */
node_group_expose_socket(ntree, sock, in_out);
}
-/**** For Loop ****/
-
-/* Essentially a group node with slightly different behavior.
- * The internal tree is executed several times, with each output being re-used
- * as an input in the next iteration. For this purpose, input and output socket
- * lists are kept identical!
- */
-
-bNodeTemplate node_forloop_template(bNode *node)
-{
- bNodeTemplate ntemp;
- ntemp.type = NODE_FORLOOP;
- ntemp.ngroup = (bNodeTree*)node->id;
- return ntemp;
-}
-
-void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
-{
- bNodeSocket *sock;
-
- node->id = (ID*)ntemp->ngroup;
-
- 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.
- */
- if (ntemp->ngroup) {
- bNodeSocket *gsock;
- for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next)
- node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock);
- for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next)
- node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock);
- }
-}
-
-void node_forloop_init_tree(bNodeTree *ntree)
-{
- bNodeSocket *sock;
- sock = node_group_add_socket(ntree, "Iteration", SOCK_FLOAT, SOCK_IN);
- sock->flag |= SOCK_INTERNAL;
-}
-
-static void loop_sync(bNodeTree *ntree, int sync_in_out)
-{
- bNodeSocket *sock, *sync, *nsync, *mirror;
- ListBase *sync_lb;
-
- if (sync_in_out==SOCK_IN) {
- sock = ntree->outputs.first;
-
- sync = ntree->inputs.first;
- sync_lb = &ntree->inputs;
- }
- else {
- sock = ntree->inputs.first;
-
- sync = ntree->outputs.first;
- sync_lb = &ntree->outputs;
- }
-
- /* NB: the sock->storage pointer is used here directly to store the own_index int
- * out the mirrored socket counterpart!
- */
-
- while (sock) {
- /* skip static and internal sockets on the sync side (preserves socket order!) */
- while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC)))
- sync = sync->next;
-
- if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) {
- if (sock->storage==NULL) {
- /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */
- mirror = node_group_expose_socket(ntree, sock, sync_in_out);
- /* store the mirror index */
- sock->storage = SET_INT_IN_POINTER(mirror->own_index);
- mirror->storage = SET_INT_IN_POINTER(sock->own_index);
- /* move mirror to the right place */
- BLI_remlink(sync_lb, mirror);
- if (sync)
- BLI_insertlinkbefore(sync_lb, sync, mirror);
- else
- BLI_addtail(sync_lb, mirror);
- }
- else {
- /* look up the mirror socket */
- for (mirror=sync; mirror; mirror=mirror->next)
- if (mirror->own_index == GET_INT_FROM_POINTER(sock->storage))
- break;
- /* make sure the name is the same (only for identification by user, no deeper meaning) */
- BLI_strncpy(mirror->name, sock->name, sizeof(mirror->name));
- /* fix the socket order if necessary */
- if (mirror != sync) {
- BLI_remlink(sync_lb, mirror);
- BLI_insertlinkbefore(sync_lb, sync, mirror);
- }
- else
- sync = sync->next;
- }
- }
-
- sock = sock->next;
- }
-
- /* remaining sockets in sync_lb are leftovers from deleted sockets, remove them */
- while (sync) {
- nsync = sync->next;
- if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC))
- node_group_remove_socket(ntree, sync, sync_in_out);
- sync = nsync;
- }
-}
-
-void node_loop_update_tree(bNodeTree *ngroup)
-{
- /* make sure inputs & outputs are identical */
- if (ngroup->update & NTREE_UPDATE_GROUP_IN)
- loop_sync(ngroup, SOCK_OUT);
- if (ngroup->update & NTREE_UPDATE_GROUP_OUT)
- loop_sync(ngroup, SOCK_IN);
-}
-
-void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp)
-{
- bNodeSocket *sock;
-
- node->id = (ID*)ntemp->ngroup;
-
- 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;
-
- /* NB: group socket input/output roles are inverted internally!
- * Group "inputs" work as outputs in links and vice versa.
- */
- if (ntemp->ngroup) {
- bNodeSocket *gsock;
- for (gsock=ntemp->ngroup->inputs.first; gsock; gsock=gsock->next)
- node_group_add_extern_socket(ntree, &node->inputs, SOCK_IN, gsock);
- for (gsock=ntemp->ngroup->outputs.first; gsock; gsock=gsock->next)
- node_group_add_extern_socket(ntree, &node->outputs, SOCK_OUT, gsock);
- }
-}
-
-void node_whileloop_init_tree(bNodeTree *ntree)
-{
- bNodeSocket *sock;
- sock = node_group_add_socket(ntree, "Condition", SOCK_FLOAT, SOCK_OUT);
- sock->flag |= SOCK_INTERNAL;
-}
-
-bNodeTemplate node_whileloop_template(bNode *node)
-{
- bNodeTemplate ntemp;
- ntemp.type = NODE_WHILELOOP;
- ntemp.ngroup = (bNodeTree*)node->id;
- return ntemp;
-}
-
/**** FRAME ****/
static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
struct bNodeTree;
void node_group_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
-void node_forloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
-void node_whileloop_init(struct bNodeTree *ntree, struct bNode *node, struct bNodeTemplate *ntemp);
-
-void node_forloop_init_tree(struct bNodeTree *ntree);
-void node_whileloop_init_tree(struct bNodeTree *ntree);
-
const char *node_group_label(struct bNode *node);
-
struct bNodeTemplate node_group_template(struct bNode *node);
-struct bNodeTemplate node_forloop_template(struct bNode *node);
-struct bNodeTemplate node_whileloop_template(struct bNode *node);
-
int node_group_valid(struct bNodeTree *ntree, struct bNodeTemplate *ntemp);
void node_group_verify(struct bNodeTree *ntree, struct bNode *node, struct ID *id);
struct bNodeTree *node_group_edit_set(struct bNode *node, int edit);
void node_group_edit_clear(bNode *node);
-void node_loop_update_tree(struct bNodeTree *ngroup);
-
void ntree_update_reroute_nodes(struct bNodeTree *ntree);
#endif
nodeRegisterType(ttype, &ntype);
}
-
-
-/**** FOR LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
- bNodeThreadStack *nts;
- int iterations= (int)in[0]->vec[0];
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- nts = ntreeGetThreadStack(exec, thread);
-
- /* "Iteration" socket */
- sock = exec->nodetree->inputs.first;
- ns = node_get_socket_stack(nts->stack, sock);
-
-// group_copy_inputs(node, in, nts->stack);
- for (iteration=0; iteration < iterations; ++iteration) {
- /* first input contains current iteration counter */
- ns->vec[0] = (float)iteration;
- ns->vec[1]=ns->vec[2]=ns->vec[3] = 0.0f;
-
-// if (iteration > 0)
-// loop_init_iteration(exec->nodetree, nts->stack);
-// ntreeExecThreadNodes(exec, nts, data, thread);
- }
-// loop_copy_outputs(node, in, out, exec->stack);
-
- ntreeReleaseThreadStack(nts);
-}
-
-void register_node_type_sh_forloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_forloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_forloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif
-
-/**** WHILE LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
- bNodeThreadStack *nts;
- int condition= (in[0]->vec[0] > 0.0f);
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- nts = ntreeGetThreadStack(exec, thread);
-
- /* "Condition" socket */
- sock = exec->nodetree->outputs.first;
- ns = node_get_socket_stack(nts->stack, sock);
-
- iteration = 0;
-// group_copy_inputs(node, in, nts->stack);
- while (condition && iteration < node->custom1) {
-// if (iteration > 0)
-// loop_init_iteration(exec->nodetree, nts->stack);
-// ntreeExecThreadNodes(exec, nts, data, thread);
-
- condition = (ns->vec[0] > 0.0f);
- ++iteration;
- }
-// loop_copy_outputs(node, in, out, exec->stack);
-
- ntreeReleaseThreadStack(nts);
-}
-
-void register_node_type_sh_whileloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_whileloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_whileloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif
nodeRegisterType(ttype, &ntype);
}
-
-
-/**** FOR LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
- bNodeThreadStack *nts;
- int iterations= (int)in[0]->vec[0];
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- nts = ntreeGetThreadStack(exec, thread);
-
- /* "Iteration" socket */
- sock = exec->nodetree->inputs.first;
- ns = node_get_socket_stack(nts->stack, sock);
-
-// group_copy_inputs(node, in, nts->stack);
- for (iteration=0; iteration < iterations; ++iteration) {
- /* first input contains current iteration counter */
- ns->vec[0] = (float)iteration;
- ns->vec[1]=ns->vec[2]=ns->vec[3] = 0.0f;
-
-// if (iteration > 0)
-// loop_init_iteration(exec->nodetree, nts->stack);
-// ntreeExecThreadNodes(exec, nts, data, thread);
- }
-// loop_copy_outputs(node, in, out, exec->stack);
-
- ntreeReleaseThreadStack(nts);
-}
-
-void register_node_type_tex_forloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_forloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_forloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif
-
-/**** WHILE LOOP ****/
-
-#if 0 /* XXX loop nodes don't work nicely with current trees */
-static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
-{
- bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
- bNodeThreadStack *nts;
- int condition= (in[0]->vec[0] > 0.0f);
- bNodeSocket *sock;
- bNodeStack *ns;
- int iteration;
-
- /* XXX same behavior as trunk: all nodes inside group are executed.
- * it's stupid, but just makes it work. compo redesign will do this better.
- */
- {
- bNode *inode;
- for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
- inode->need_exec = 1;
- }
-
- nts = ntreeGetThreadStack(exec, thread);
-
- /* "Condition" socket */
- sock = exec->nodetree->outputs.first;
- ns = node_get_socket_stack(nts->stack, sock);
-
- iteration = 0;
-// group_copy_inputs(node, in, nts->stack);
- while (condition && iteration < node->custom1) {
-// if (iteration > 0)
-// loop_init_iteration(exec->nodetree, nts->stack);
-// ntreeExecThreadNodes(exec, nts, data, thread);
-
- condition = (ns->vec[0] > 0.0f);
- ++iteration;
- }
-// loop_copy_outputs(node, in, out, exec->stack);
-
- ntreeReleaseThreadStack(nts);
-}
-
-void register_node_type_tex_whileloop(bNodeTreeType *ttype)
-{
- static bNodeType ntype;
-
- node_type_base(ttype, &ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS);
- node_type_socket_templates(&ntype, NULL, NULL);
- node_type_size(&ntype, 120, 60, 200);
- node_type_label(&ntype, node_group_label);
- node_type_init(&ntype, node_whileloop_init);
- node_type_valid(&ntype, node_group_valid);
- node_type_template(&ntype, node_whileloop_template);
- node_type_update(&ntype, NULL, node_group_verify);
- node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree);
- node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
- node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute);
-
- nodeRegisterType(ttype, &ntype);
-}
-#endif