Blender V2.61 - r43446
|
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 }