Blender V2.61 - r43446

node_texture_output.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): Robin Allen
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "node_texture_util.h"
00034 #include "NOD_texture.h"
00035 
00036 /* **************** COMPOSITE ******************** */
00037 static bNodeSocketTemplate inputs[]= {
00038     { SOCK_RGBA,   1, "Color",  0.0f, 0.0f, 0.0f, 1.0f},
00039     { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION},
00040     { -1, 0, "" }
00041 };
00042 
00043 /* applies to render pipeline */
00044 static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
00045 {
00046     TexCallData *cdata = (TexCallData *)data;
00047     TexResult *target = cdata->target;
00048     
00049     if(cdata->do_preview) {
00050         TexParams params;
00051         params_from_cdata(&params, cdata);
00052 
00053         if(in[1] && in[1]->hasinput && !in[0]->hasinput)
00054             tex_input_rgba(&target->tr, in[1], &params, cdata->thread);
00055         else
00056             tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
00057         tex_do_preview(node, params.co, &target->tr);
00058     }
00059     else {
00060         /* 0 means don't care, so just use first */
00061         if(cdata->which_output == node->custom1 || (cdata->which_output == 0 && node->custom1 == 1)) {
00062             TexParams params;
00063             params_from_cdata(&params, cdata);
00064             
00065             tex_input_rgba(&target->tr, in[0], &params, cdata->thread);
00066         
00067             target->tin = (target->tr + target->tg + target->tb) / 3.0f;
00068             target->talpha = 1;
00069         
00070             if(target->nor) {
00071                 if(in[1] && in[1]->hasinput)
00072                     tex_input_vec(target->nor, in[1], &params, cdata->thread);
00073                 else
00074                     target->nor = NULL;
00075             }
00076         }
00077     }
00078 }
00079 
00080 static void unique_name(bNode *node)
00081 {
00082     TexNodeOutput *tno = (TexNodeOutput *)node->storage;
00083     char *new_name = NULL;
00084     int new_len = 0;
00085     int suffix;
00086     bNode *i;
00087     char *name = tno->name;
00088     
00089     i = node;
00090     while(i->prev) i = i->prev;
00091     for(; i; i=i->next) {
00092         if(
00093             i == node ||
00094             i->type != TEX_NODE_OUTPUT ||
00095             strcmp(name, ((TexNodeOutput*)(i->storage))->name)
00096         )
00097             continue;
00098         
00099         if(!new_name) {
00100             int len = strlen(name);
00101             if(len >= 4 && sscanf(name + len - 4, ".%03d", &suffix) == 1) {
00102                 new_len = len;
00103             } else {
00104                 suffix = 0;
00105                 new_len = len + 4;
00106                 if(new_len > (sizeof(tno->name) - 1))
00107                     new_len = (sizeof(tno->name) - 1);
00108             }
00109             
00110             new_name = MEM_mallocN(new_len + 1, "new_name");
00111             strcpy(new_name, name);
00112             name = new_name;
00113         }
00114         sprintf(new_name + new_len - 4, ".%03d", ++suffix);
00115     }
00116     
00117     if(new_name) {
00118         strcpy(tno->name, new_name);
00119         MEM_freeN(new_name);
00120     }
00121 }
00122 
00123 static void assign_index(struct bNode *node)
00124 {
00125     bNode *tnode;
00126     int index = 1;
00127     
00128     tnode = node;
00129     while(tnode->prev)
00130         tnode = tnode->prev;
00131     
00132     check_index:
00133     for(; tnode; tnode= tnode->next)
00134         if(tnode->type == TEX_NODE_OUTPUT && tnode != node)
00135             if(tnode->custom1 == index) {
00136                 index ++;
00137                 goto check_index;
00138             }
00139             
00140     node->custom1 = index;
00141 }
00142 
00143 static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
00144 {
00145     TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
00146     node->storage= tno;
00147     
00148     strcpy(tno->name, "Default");
00149     unique_name(node);
00150     assign_index(node);
00151 }
00152 
00153 static void copy(bNode *orig, bNode *new)
00154 {
00155     node_copy_standard_storage(orig, new);
00156     unique_name(new);
00157     assign_index(new);
00158 }
00159 
00160 void register_node_type_tex_output(bNodeTreeType *ttype)
00161 {
00162     static bNodeType ntype;
00163     
00164     node_type_base(ttype, &ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW|NODE_OPTIONS);
00165     node_type_socket_templates(&ntype, inputs, NULL);
00166     node_type_size(&ntype, 150, 60, 200);
00167     node_type_init(&ntype, init);
00168     node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy);
00169     node_type_exec(&ntype, exec);
00170     
00171     /* Do not allow muting output. */
00172     node_type_mute(&ntype, NULL, NULL);
00173     
00174     nodeRegisterType(ttype, &ntype);
00175 }