Blender V2.61 - r43446

node_texture_common.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2006 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva,
00024  * Juho Vepsäläinen
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include "DNA_node_types.h"
00035 
00036 #include "BKE_node.h"
00037 
00038 #include "node_texture_util.h"
00039 #include "node_common.h"
00040 #include "node_exec.h"
00041 
00042 static void copy_stack(bNodeStack *to, bNodeStack *from)
00043 {
00044     if (to != from) {
00045         copy_v4_v4(to->vec, from->vec);
00046         to->data = from->data;
00047         to->datatype = from->datatype;
00048         
00049         /* tag as copy to prevent freeing */
00050         to->is_copy = 1;
00051     }
00052 }
00053 
00054 /**** GROUP ****/
00055 
00056 static void *group_initexec(bNode *node)
00057 {
00058     bNodeTree *ngroup= (bNodeTree*)node->id;
00059     void *exec;
00060     
00061     /* initialize the internal node tree execution */
00062     exec = ntreeTexBeginExecTree(ngroup, 0);
00063     
00064     return exec;
00065 }
00066 
00067 static void group_freeexec(bNode *UNUSED(node), void *nodedata)
00068 {
00069     bNodeTreeExec*gexec= (bNodeTreeExec*)nodedata;
00070     
00071     ntreeTexEndExecTree(gexec, 0);
00072 }
00073 
00074 /* Copy inputs to the internal stack.
00075  * This is a shallow copy, no buffers are duplicated here!
00076  */
00077 static void group_copy_inputs(bNode *node, bNodeStack **in, bNodeStack *gstack)
00078 {
00079     bNodeSocket *sock;
00080     bNodeStack *ns;
00081     int a;
00082     for (sock=node->inputs.first, a=0; sock; sock=sock->next, ++a) {
00083         if (sock->groupsock) {
00084             ns = node_get_socket_stack(gstack, sock->groupsock);
00085             copy_stack(ns, in[a]);
00086         }
00087     }
00088 }
00089 
00090 /* Copy internal results to the external outputs.
00091  */
00092 static void group_copy_outputs(bNode *node, bNodeStack **out, bNodeStack *gstack)
00093 {
00094     bNodeSocket *sock;
00095     bNodeStack *ns;
00096     int a;
00097     for (sock=node->outputs.first, a=0; sock; sock=sock->next, ++a) {
00098         if (sock->groupsock) {
00099             ns = node_get_socket_stack(gstack, sock->groupsock);
00100             copy_stack(out[a], ns);
00101         }
00102     }
00103 }
00104 
00105 static void group_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
00106 {
00107     bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
00108     bNodeThreadStack *nts;
00109     
00110     /* XXX same behavior as trunk: all nodes inside group are executed.
00111      * it's stupid, but just makes it work. compo redesign will do this better.
00112      */
00113     {
00114         bNode *inode;
00115         for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
00116             inode->need_exec = 1;
00117     }
00118     
00119     nts = ntreeGetThreadStack(exec, thread);
00120     
00121     group_copy_inputs(node, in, nts->stack);
00122     ntreeExecThreadNodes(exec, nts, data, thread);
00123     group_copy_outputs(node, out, nts->stack);
00124     
00125     ntreeReleaseThreadStack(nts);
00126 }
00127 
00128 void register_node_type_tex_group(bNodeTreeType *ttype)
00129 {
00130     static bNodeType ntype;
00131 
00132     node_type_base(ttype, &ntype, NODE_GROUP, "Group", NODE_CLASS_GROUP, NODE_OPTIONS|NODE_CONST_OUTPUT);
00133     node_type_socket_templates(&ntype, NULL, NULL);
00134     node_type_size(&ntype, 120, 60, 200);
00135     node_type_label(&ntype, node_group_label);
00136     node_type_init(&ntype, node_group_init);
00137     node_type_valid(&ntype, node_group_valid);
00138     node_type_template(&ntype, node_group_template);
00139     node_type_update(&ntype, NULL, node_group_verify);
00140     node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
00141     node_type_exec_new(&ntype, group_initexec, group_freeexec, group_execute);
00142     
00143     nodeRegisterType(ttype, &ntype);
00144 }
00145 
00146 
00147 /**** FOR LOOP ****/
00148 
00149 #if 0 /* XXX loop nodes don't work nicely with current trees */
00150 static void forloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
00151 {
00152     bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
00153     bNodeThreadStack *nts;
00154     int iterations= (int)in[0]->vec[0];
00155     bNodeSocket *sock;
00156     bNodeStack *ns;
00157     int iteration;
00158     
00159     /* XXX same behavior as trunk: all nodes inside group are executed.
00160      * it's stupid, but just makes it work. compo redesign will do this better.
00161      */
00162     {
00163         bNode *inode;
00164         for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
00165             inode->need_exec = 1;
00166     }
00167     
00168     nts = ntreeGetThreadStack(exec, thread);
00169     
00170     /* "Iteration" socket */
00171     sock = exec->nodetree->inputs.first;
00172     ns = node_get_socket_stack(nts->stack, sock);
00173     
00174 //  group_copy_inputs(node, in, nts->stack);
00175     for (iteration=0; iteration < iterations; ++iteration) {
00176         /* first input contains current iteration counter */
00177         ns->vec[0] = (float)iteration;
00178         ns->vec[1]=ns->vec[2]=ns->vec[3] = 0.0f;
00179         
00180 //      if (iteration > 0)
00181 //          loop_init_iteration(exec->nodetree, nts->stack);
00182 //      ntreeExecThreadNodes(exec, nts, data, thread);
00183     }
00184 //  loop_copy_outputs(node, in, out, exec->stack);
00185     
00186     ntreeReleaseThreadStack(nts);
00187 }
00188 
00189 void register_node_type_tex_forloop(bNodeTreeType *ttype)
00190 {
00191     static bNodeType ntype;
00192 
00193     node_type_base(ttype, &ntype, NODE_FORLOOP, "For", NODE_CLASS_GROUP, NODE_OPTIONS);
00194     node_type_socket_templates(&ntype, NULL, NULL);
00195     node_type_size(&ntype, 120, 60, 200);
00196     node_type_label(&ntype, node_group_label);
00197     node_type_init(&ntype, node_forloop_init);
00198     node_type_valid(&ntype, node_group_valid);
00199     node_type_template(&ntype, node_forloop_template);
00200     node_type_update(&ntype, NULL, node_group_verify);
00201     node_type_tree(&ntype, node_forloop_init_tree, node_loop_update_tree);
00202     node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
00203     node_type_exec_new(&ntype, group_initexec, group_freeexec, forloop_execute);
00204     
00205     nodeRegisterType(ttype, &ntype);
00206 }
00207 #endif
00208 
00209 /**** WHILE LOOP ****/
00210 
00211 #if 0 /* XXX loop nodes don't work nicely with current trees */
00212 static void whileloop_execute(void *data, int thread, struct bNode *node, void *nodedata, struct bNodeStack **in, struct bNodeStack **out)
00213 {
00214     bNodeTreeExec *exec= (bNodeTreeExec*)nodedata;
00215     bNodeThreadStack *nts;
00216     int condition= (in[0]->vec[0] > 0.0f);
00217     bNodeSocket *sock;
00218     bNodeStack *ns;
00219     int iteration;
00220     
00221     /* XXX same behavior as trunk: all nodes inside group are executed.
00222      * it's stupid, but just makes it work. compo redesign will do this better.
00223      */
00224     {
00225         bNode *inode;
00226         for (inode=exec->nodetree->nodes.first; inode; inode=inode->next)
00227             inode->need_exec = 1;
00228     }
00229     
00230     nts = ntreeGetThreadStack(exec, thread);
00231     
00232     /* "Condition" socket */
00233     sock = exec->nodetree->outputs.first;
00234     ns = node_get_socket_stack(nts->stack, sock);
00235     
00236     iteration = 0;
00237 //  group_copy_inputs(node, in, nts->stack);
00238     while (condition && iteration < node->custom1) {
00239 //      if (iteration > 0)
00240 //          loop_init_iteration(exec->nodetree, nts->stack);
00241 //      ntreeExecThreadNodes(exec, nts, data, thread);
00242         
00243         condition = (ns->vec[0] > 0.0f);
00244         ++iteration;
00245     }
00246 //  loop_copy_outputs(node, in, out, exec->stack);
00247     
00248     ntreeReleaseThreadStack(nts);
00249 }
00250 
00251 void register_node_type_tex_whileloop(bNodeTreeType *ttype)
00252 {
00253     static bNodeType ntype;
00254 
00255     node_type_base(ttype, &ntype, NODE_WHILELOOP, "While", NODE_CLASS_GROUP, NODE_OPTIONS);
00256     node_type_socket_templates(&ntype, NULL, NULL);
00257     node_type_size(&ntype, 120, 60, 200);
00258     node_type_label(&ntype, node_group_label);
00259     node_type_init(&ntype, node_whileloop_init);
00260     node_type_valid(&ntype, node_group_valid);
00261     node_type_template(&ntype, node_whileloop_template);
00262     node_type_update(&ntype, NULL, node_group_verify);
00263     node_type_tree(&ntype, node_whileloop_init_tree, node_loop_update_tree);
00264     node_type_group_edit(&ntype, node_group_edit_get, node_group_edit_set, node_group_edit_clear);
00265     node_type_exec_new(&ntype, group_initexec, group_freeexec, whileloop_execute);
00266     
00267     nodeRegisterType(ttype, &ntype);
00268 }
00269 #endif