Blender V2.61 - r43446

node_texture_tree.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) 2007 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s):
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <string.h>
00034 
00035 #include "DNA_texture_types.h"
00036 #include "DNA_node_types.h"
00037 
00038 #include "BLI_listbase.h"
00039 #include "BLI_threads.h"
00040 #include "BLI_utildefines.h"
00041 
00042 #include "BLF_translation.h"
00043 
00044 #include "BKE_global.h"
00045 #include "BKE_main.h"
00046 #include "BKE_node.h"
00047 
00048 #include "node_exec.h"
00049 #include "node_util.h"
00050 #include "NOD_texture.h"
00051 #include "node_texture_util.h"
00052 
00053 #include "RE_pipeline.h"
00054 #include "RE_shader_ext.h"
00055 
00056 
00057 static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func)
00058 {
00059     Tex *tx;
00060     for(tx= main->tex.first; tx; tx= tx->id.next) {
00061         if(tx->nodetree) {
00062             func(calldata, &tx->id, tx->nodetree);
00063         }
00064     }
00065 }
00066 
00067 static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func)
00068 {
00069     func(calldata, NODE_CLASS_INPUT, IFACE_("Input"));
00070     func(calldata, NODE_CLASS_OUTPUT, IFACE_("Output"));
00071     func(calldata, NODE_CLASS_OP_COLOR, IFACE_("Color"));
00072     func(calldata, NODE_CLASS_PATTERN, IFACE_("Patterns"));
00073     func(calldata, NODE_CLASS_TEXTURE, IFACE_("Textures"));
00074     func(calldata, NODE_CLASS_CONVERTOR, IFACE_("Convertor"));
00075     func(calldata, NODE_CLASS_DISTORT, IFACE_("Distort"));
00076     func(calldata, NODE_CLASS_GROUP, IFACE_("Group"));
00077     func(calldata, NODE_CLASS_LAYOUT, IFACE_("Layout"));
00078 }
00079 
00080 static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
00081 {
00082     bNode *lnode;
00083     
00084     /* copy over contents of previews */
00085     for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) {
00086         if(ntreeNodeExists(ntree, lnode->new_node)) {
00087             bNode *node= lnode->new_node;
00088             
00089             if(node->preview && node->preview->rect) {
00090                 if(lnode->preview && lnode->preview->rect) {
00091                     int xsize= node->preview->xsize;
00092                     int ysize= node->preview->ysize;
00093                     memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4);
00094                 }
00095             }
00096         }
00097     }
00098 }
00099 
00100 bNodeTreeType ntreeType_Texture = {
00101     /* type */              NTREE_TEXTURE,
00102     /* id_name */           "NTTexture Nodetree",
00103     
00104     /* node_types */        { NULL, NULL },
00105     
00106     /* free_cache */            NULL,
00107     /* free_node_cache */       NULL,
00108     /* foreach_nodetree */  foreach_nodetree,
00109     /* foreach_nodeclass */ foreach_nodeclass,
00110     /* localize */          NULL,
00111     /* local_sync */        local_sync,
00112     /* local_merge */       NULL,
00113     /* update */            NULL,
00114     /* update_node */       NULL,
00115     /* validate_link */     NULL,
00116     /* mute node */         node_tex_pass_on,
00117     /* mute links node */   node_mute_get_links,
00118     /* gpu mute node */     NULL
00119 };
00120 
00121 int ntreeTexTagAnimated(bNodeTree *ntree)
00122 {
00123     bNode *node;
00124     
00125     if(ntree==NULL) return 0;
00126     
00127     for(node= ntree->nodes.first; node; node= node->next) {
00128         if(node->type==TEX_NODE_CURVE_TIME) {
00129             nodeUpdate(ntree, node);
00130             return 1;
00131         }
00132         else if(node->type==NODE_GROUP) {
00133             if( ntreeTexTagAnimated((bNodeTree *)node->id) ) {
00134                 return 1;
00135             }
00136         }
00137     }
00138     
00139     return 0;
00140 }
00141 
00142 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
00143  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
00144  */
00145 bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree, int use_tree_data)
00146 {
00147     bNodeTreeExec *exec;
00148     bNode *node;
00149     
00150     if (use_tree_data) {
00151         /* XXX hack: prevent exec data from being generated twice.
00152          * this should be handled by the renderer!
00153          */
00154         if (ntree->execdata)
00155             return ntree->execdata;
00156     }
00157     
00158     /* common base initialization */
00159     exec = ntree_exec_begin(ntree);
00160     
00161     /* allocate the thread stack listbase array */
00162     exec->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
00163     
00164     for(node= exec->nodetree->nodes.first; node; node= node->next)
00165         node->need_exec= 1;
00166     
00167     if (use_tree_data) {
00168         /* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
00169          * which only store the ntree pointer. Should be fixed at some point!
00170          */
00171         ntree->execdata = exec;
00172     }
00173     
00174     return exec;
00175 }
00176 
00177 /* free texture delegates */
00178 static void tex_free_delegates(bNodeTreeExec *exec)
00179 {
00180     bNodeThreadStack *nts;
00181     bNodeStack *ns;
00182     int th, a;
00183     
00184     for(th=0; th<BLENDER_MAX_THREADS; th++)
00185         for(nts=exec->threadstack[th].first; nts; nts=nts->next)
00186             for(ns= nts->stack, a=0; a<exec->stacksize; a++, ns++)
00187                 if(ns->data && !ns->is_copy)
00188                     MEM_freeN(ns->data);
00189 }
00190 
00191 /* XXX Group nodes must set use_tree_data to false, since their trees can be shared by multiple nodes.
00192  * If use_tree_data is true, the ntree->execdata pointer is checked to avoid multiple execution of top-level trees.
00193  */
00194 void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data)
00195 {
00196     if(exec) {
00197         bNodeTree *ntree= exec->nodetree;
00198         bNodeThreadStack *nts;
00199         int a;
00200         
00201         if(exec->threadstack) {
00202             tex_free_delegates(exec);
00203             
00204             for(a=0; a<BLENDER_MAX_THREADS; a++) {
00205                 for(nts=exec->threadstack[a].first; nts; nts=nts->next)
00206                     if (nts->stack) MEM_freeN(nts->stack);
00207                 BLI_freelistN(&exec->threadstack[a]);
00208             }
00209             
00210             MEM_freeN(exec->threadstack);
00211             exec->threadstack= NULL;
00212         }
00213         
00214         ntree_exec_end(exec);
00215         
00216         if (use_tree_data) {
00217             /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
00218             ntree->execdata = NULL;
00219         }
00220     }
00221 }
00222 
00223 int ntreeTexExecTree(
00224     bNodeTree *nodes,
00225     TexResult *texres,
00226     float *co,
00227     float *dxt, float *dyt,
00228     int osatex,
00229     short thread, 
00230     Tex *UNUSED(tex), 
00231     short which_output, 
00232     int cfra,
00233     int preview,
00234     ShadeInput *shi,
00235     MTex *mtex
00236 ){
00237     TexCallData data;
00238     float *nor= texres->nor;
00239     int retval = TEX_INT;
00240     bNodeThreadStack *nts = NULL;
00241     bNodeTreeExec *exec= nodes->execdata;
00242 
00243     data.co = co;
00244     data.dxt = dxt;
00245     data.dyt = dyt;
00246     data.osatex = osatex;
00247     data.target = texres;
00248     data.do_preview = preview;
00249     data.thread = thread;
00250     data.which_output = which_output;
00251     data.cfra= cfra;
00252     data.mtex= mtex;
00253     data.shi= shi;
00254     
00255     /* ensure execdata is only initialized once */
00256     if (!exec) {
00257         BLI_lock_thread(LOCK_NODES);
00258         if(!nodes->execdata)
00259             ntreeTexBeginExecTree(nodes, 1);
00260         BLI_unlock_thread(LOCK_NODES);
00261 
00262         exec= nodes->execdata;
00263     }
00264     
00265     nts= ntreeGetThreadStack(exec, thread);
00266     ntreeExecThreadNodes(exec, nts, &data, thread);
00267     ntreeReleaseThreadStack(nts);
00268 
00269     if(texres->nor) retval |= TEX_NOR;
00270     retval |= TEX_RGB;
00271     /* confusing stuff; the texture output node sets this to NULL to indicate no normal socket was set
00272        however, the texture code checks this for other reasons (namely, a normal is required for material) */
00273     texres->nor= nor;
00274 
00275     return retval;
00276 }