Blender  V2.59
SHD_util.c
Go to the documentation of this file.
00001 /*
00002  * $Id: SHD_util.c 38506 2011-07-19 08:31:53Z jbakker $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version. 
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2005 Blender Foundation.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #include "SHD_util.h"
00036 
00037 
00038 
00039 
00040 
00041 /* ****** */
00042 
00043 void nodestack_get_vec(float *in, short type_in, bNodeStack *ns)
00044 {
00045         float *from= ns->vec;
00046                 
00047         if(type_in==SOCK_VALUE) {
00048                 if(ns->sockettype==SOCK_VALUE)
00049                         *in= *from;
00050                 else 
00051                         *in= 0.333333f*(from[0]+from[1]+from[2]);
00052         }
00053         else if(type_in==SOCK_VECTOR) {
00054                 if(ns->sockettype==SOCK_VALUE) {
00055                         in[0]= from[0];
00056                         in[1]= from[0];
00057                         in[2]= from[0];
00058                 }
00059                 else {
00060                         VECCOPY(in, from);
00061                 }
00062         }
00063         else { /* type_in==SOCK_RGBA */
00064                 if(ns->sockettype==SOCK_RGBA) {
00065                         QUATCOPY(in, from);
00066                 }
00067                 else if(ns->sockettype==SOCK_VALUE) {
00068                         in[0]= from[0];
00069                         in[1]= from[0];
00070                         in[2]= from[0];
00071                         in[3]= 1.0f;
00072                 }
00073                 else {
00074                         VECCOPY(in, from);
00075                         in[3]= 1.0f;
00076                 }
00077         }
00078 }
00079 
00080 
00081 /* ******************* execute and parse ************ */
00082 
00083 void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
00084 {
00085         ShaderCallData scd;
00086         /*
00087          @note: preserve material from ShadeInput for material id, nodetree execs change it
00088          fix for bug "[#28012] Mat ID messy with shader nodes"
00089          */
00090         Material *mat = shi->mat;
00091         /* convert caller data to struct */
00092         scd.shi= shi;
00093         scd.shr= shr;
00094         
00095         /* each material node has own local shaderesult, with optional copying */
00096         memset(shr, 0, sizeof(ShadeResult));
00097                    
00098         ntreeExecTree(ntree, &scd, shi->thread);        /* threads */
00099         // @note: set material back to preserved material
00100         shi->mat = mat;
00101         /* better not allow negative for now */
00102         if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f;
00103         if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f;
00104         if(shr->combined[2]<0.0f) shr->combined[2]= 0.0f;
00105         
00106 }
00107 
00108 /* go over all used Geometry and Texture nodes, and return a texco flag */
00109 /* no group inside needed, this function is called for groups too */
00110 void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode)
00111 {
00112         bNode *node;
00113         bNodeSocket *sock;
00114         int a;
00115         
00116         ntreeSocketUseFlags(ntree);
00117 
00118         for(node= ntree->nodes.first; node; node= node->next) {
00119                 if(node->type==SH_NODE_TEXTURE) {
00120                         if((r_mode & R_OSA) && node->id) {
00121                                 Tex *tex= (Tex *)node->id;
00122                                 if ELEM3(tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) 
00123                                         *texco |= TEXCO_OSA|NEED_UV;
00124                         }
00125                         /* usability exception... without input we still give the node orcos */
00126                         sock= node->inputs.first;
00127                         if(sock==NULL || sock->link==NULL)
00128                                 *texco |= TEXCO_ORCO|NEED_UV;
00129                 }
00130                 else if(node->type==SH_NODE_GEOMETRY) {
00131                         /* note; sockets always exist for the given type! */
00132                         for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
00133                                 if(sock->flag & SOCK_IN_USE) {
00134                                         switch(a) {
00135                                                 case GEOM_OUT_GLOB: 
00136                                                         *texco |= TEXCO_GLOB|NEED_UV; break;
00137                                                 case GEOM_OUT_VIEW: 
00138                                                         *texco |= TEXCO_VIEW|NEED_UV; break;
00139                                                 case GEOM_OUT_ORCO: 
00140                                                         *texco |= TEXCO_ORCO|NEED_UV; break;
00141                                                 case GEOM_OUT_UV: 
00142                                                         *texco |= TEXCO_UV|NEED_UV; break;
00143                                                 case GEOM_OUT_NORMAL: 
00144                                                         *texco |= TEXCO_NORM|NEED_UV; break;
00145                                                 case GEOM_OUT_VCOL:
00146                                                         *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break;
00147                                         }
00148                                 }
00149                         }
00150                 }
00151         }
00152 }
00153 
00154 /* nodes that use ID data get synced with local data */
00155 void nodeShaderSynchronizeID(bNode *node, int copyto)
00156 {
00157         if(node->id==NULL) return;
00158         
00159         if(ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) {
00160                 bNodeSocket *sock;
00161                 Material *ma= (Material *)node->id;
00162                 int a;
00163                 
00164                 /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */
00165                 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
00166                         if(!(sock->flag & SOCK_HIDDEN)) {
00167                                 if(copyto) {
00168                                         switch(a) {
00169                                                 case MAT_IN_COLOR:
00170                                                         VECCOPY(&ma->r, sock->ns.vec); break;
00171                                                 case MAT_IN_SPEC:
00172                                                         VECCOPY(&ma->specr, sock->ns.vec); break;
00173                                                 case MAT_IN_REFL:
00174                                                         ma->ref= sock->ns.vec[0]; break;
00175                                                 case MAT_IN_MIR:
00176                                                         VECCOPY(&ma->mirr, sock->ns.vec); break;
00177                                                 case MAT_IN_AMB:
00178                                                         ma->amb= sock->ns.vec[0]; break;
00179                                                 case MAT_IN_EMIT:
00180                                                         ma->emit= sock->ns.vec[0]; break;
00181                                                 case MAT_IN_SPECTRA:
00182                                                         ma->spectra= sock->ns.vec[0]; break;
00183                                                 case MAT_IN_RAY_MIRROR:
00184                                                         ma->ray_mirror= sock->ns.vec[0]; break;
00185                                                 case MAT_IN_ALPHA:
00186                                                         ma->alpha= sock->ns.vec[0]; break;
00187                                                 case MAT_IN_TRANSLUCENCY:
00188                                                         ma->translucency= sock->ns.vec[0]; break;
00189                                         }
00190                                 }
00191                                 else {
00192                                         switch(a) {
00193                                                 case MAT_IN_COLOR:
00194                                                         VECCOPY(sock->ns.vec, &ma->r); break;
00195                                                 case MAT_IN_SPEC:
00196                                                         VECCOPY(sock->ns.vec, &ma->specr); break;
00197                                                 case MAT_IN_REFL:
00198                                                         sock->ns.vec[0]= ma->ref; break;
00199                                                 case MAT_IN_MIR:
00200                                                         VECCOPY(sock->ns.vec, &ma->mirr); break;
00201                                                 case MAT_IN_AMB:
00202                                                         sock->ns.vec[0]= ma->amb; break;
00203                                                 case MAT_IN_EMIT:
00204                                                         sock->ns.vec[0]= ma->emit; break;
00205                                                 case MAT_IN_SPECTRA:
00206                                                         sock->ns.vec[0]= ma->spectra; break;
00207                                                 case MAT_IN_RAY_MIRROR:
00208                                                         sock->ns.vec[0]= ma->ray_mirror; break;
00209                                                 case MAT_IN_ALPHA:
00210                                                         sock->ns.vec[0]= ma->alpha; break;
00211                                                 case MAT_IN_TRANSLUCENCY:
00212                                                         sock->ns.vec[0]= ma->translucency; break;
00213                                         }
00214                                 }
00215                         }
00216                 }
00217         }
00218         
00219 }