From 0509409c6b319a73fc76a2cb5ccfcd438cdcd7a4 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Nov 2008 19:14:46 +0000 Subject: [PATCH] Bah, two more files! --- source/blender/nodes/TEX_node.h | 70 +++++++ source/blender/nodes/intern/TEX_util.c | 271 +++++++++++++++++++++++++ 2 files changed, 341 insertions(+) create mode 100644 source/blender/nodes/TEX_node.h create mode 100644 source/blender/nodes/intern/TEX_util.c diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h new file mode 100644 index 00000000000..6be2123b96d --- /dev/null +++ b/source/blender/nodes/TEX_node.h @@ -0,0 +1,70 @@ +/** + * $Id: CMP_node.h 12429 2007-10-29 14:37:19Z bebraw $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef TEX_NODE_H +#define TEX_NODE_H + +#include "BKE_node.h" + + +/* ****************** types array for all texture nodes ****************** */ + +extern bNodeType tex_node_math; +extern bNodeType tex_node_mix_rgb; +extern bNodeType tex_node_valtorgb; +extern bNodeType tex_node_rgbtobw; +extern bNodeType tex_node_output; +extern bNodeType tex_node_viewer; +extern bNodeType tex_node_checker; +extern bNodeType tex_node_texture; +extern bNodeType tex_node_bricks; +extern bNodeType tex_node_image; +extern bNodeType tex_node_curve_rgb; +extern bNodeType tex_node_curve_time; +extern bNodeType tex_node_invert; +extern bNodeType tex_node_hue_sat; + +extern bNodeType tex_node_rotate; +extern bNodeType tex_node_translate; + +extern bNodeType tex_node_proc_voronoi; +extern bNodeType tex_node_proc_blend; +extern bNodeType tex_node_proc_magic; +extern bNodeType tex_node_proc_marble; +extern bNodeType tex_node_proc_clouds; +extern bNodeType tex_node_proc_wood; +extern bNodeType tex_node_proc_musgrave; +extern bNodeType tex_node_proc_noise; +extern bNodeType tex_node_proc_stucci; +extern bNodeType tex_node_proc_distnoise; + +#endif diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c new file mode 100644 index 00000000000..3a0094e1173 --- /dev/null +++ b/source/blender/nodes/intern/TEX_util.c @@ -0,0 +1,271 @@ +/** + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* + HOW TEXTURE NODES WORK + + In contrast to Shader nodes, which place a colour into the output + stack when executed, Texture nodes place a TexDelegate* there. To + obtain a colour value from this, a node further up the chain reads + the TexDelegate* from its input stack, and uses tex_call_delegate to + retrieve the colour from the delegate. +*/ + +#include +#include "TEX_util.h" + +#define PREV_RES 128 /* default preview resolution */ + +void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread) +{ + dg->fn(out, coord, dg->node, dg->in, thread); +} + +void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread) +{ + TexDelegate *dg = in->data; + if(dg) { + tex_call_delegate(dg, out, coord, thread); + + if(in->hasoutput && in->sockettype == SOCK_VALUE) { + out[1] = out[2] = out[0]; + out[3] = 1; + } + } + else { + QUATCOPY(out, in->vec); + } +} + +void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread) +{ + tex_input_vec(out, in, coord, thread); + + if(in->hasoutput && in->sockettype == SOCK_VECTOR) { + out[0] = out[0] * .5f + .5f; + out[1] = out[1] * .5f + .5f; + out[2] = out[2] * .5f + .5f; + out[3] = 1; + } +} + +float tex_input_value(bNodeStack *in, float *coord, short thread) +{ + float out[4]; + tex_input_vec(out, in, coord, thread); + return out[0]; +} + +static void init_preview(bNode *node) +{ + int xsize = node->prvr.xmax - node->prvr.xmin; + int ysize = node->prvr.ymax - node->prvr.ymin; + + if(xsize == 0) { + xsize = PREV_RES; + ysize = PREV_RES; + } + + if(node->preview==NULL) + node->preview= MEM_callocN(sizeof(bNodePreview), "node preview"); + + if(node->preview->rect) + if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) { + MEM_freeN(node->preview->rect); + node->preview->rect= NULL; + } + + if(node->preview->rect==NULL) { + node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect"); + node->preview->xsize= xsize; + node->preview->ysize= ysize; + } +} + +void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata) +{ + int x, y; + float *result; + bNodePreview *preview; + + if(!cdata->do_preview) + return; + + if(!(node->typeinfo->flag & NODE_PREVIEW)) + return; + + init_preview(node); + + preview = node->preview; + + for(x=0; xxsize; x++) + for(y=0; yysize; y++) + { + cdata->coord[0] = ((float) x / preview->xsize) * 2 - 1; + cdata->coord[1] = ((float) y / preview->ysize) * 2 - 1; + + result = preview->rect + 4 * (preview->xsize*y + x); + + tex_input_rgba(result, ns, cdata->coord, cdata->thread); + } +} + +void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn) +{ + TexDelegate *dg; + if(!out->data) + /* Freed in tex_end_exec (node.c) */ + dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); + else + dg = out->data; + + + dg->fn = texfn; + dg->node = node; + memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); + dg->type = out->sockettype; +} + +void ntreeTexCheckCyclics(struct bNodeTree *ntree) +{ + bNode *node; + for(node= ntree->nodes.first; node; node= node->next) { + + if(node->type == TEX_NODE_TEXTURE && node->id) + { + /* custom2 stops the node from rendering */ + if(node->custom1) { + node->custom2 = 1; + node->custom1 = 0; + } else { + Tex *tex = (Tex *)node->id; + + node->custom2 = 0; + + node->custom1 = 1; + if(tex->use_nodes && tex->nodetree) { + ntreeTexCheckCyclics(tex->nodetree); + } + node->custom1 = 0; + } + } + + } +} + +void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do_preview, short thread, Tex *tex, short which_output) +{ + TexResult dummy_texres; + TexCallData data; + + if(!texres) texres = &dummy_texres; + data.coord = coord; + data.target = texres; + data.do_preview = do_preview; + data.thread = thread; + data.which_output = which_output; + + ntreeExecTree(nodes, &data, thread); +} + +void ntreeTexUpdatePreviews(bNodeTree* nodetree) +{ + Tex *tex; + float coord[] = {0,0,0}; + TexResult dummy_texres; + + for(tex= G.main->tex.first; tex; tex= tex->id.next) + if(tex->nodetree == nodetree) break; + if(!tex) return; + + dummy_texres.nor = 0; + + ntreeBeginExecTree(nodetree); + ntreeTexExecTree(nodetree, &dummy_texres, coord, 1, 0, tex, 0); + ntreeEndExecTree(nodetree); + + BIF_preview_changed(ID_TE); +} + +char* ntreeTexOutputMenu(bNodeTree *ntree) +{ + bNode *node; + int len = 1; + char *str; + char ctrl[4]; + int index = 0; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->type == TEX_NODE_OUTPUT) { + len += strlen( + ((TexNodeOutput*)node->storage)->name + ) + strlen(" %xNNN|"); + index ++; + + if(node->custom1 > 999) { + printf("Error: too many outputs"); + break; + } + } + + str = malloc(len * sizeof(char)); + *str = 0; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->type == TEX_NODE_OUTPUT) { + strcat(str, ((TexNodeOutput*)node->storage)->name); + strcat(str, " %x"); + + sprintf(ctrl, "%d", node->custom1); + strcat(str, ctrl); + + if(--index) + strcat(str, "|"); + else + break; + } + + return str; +} + +void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node) +{ + bNode *tnode; + int index = 0; + + check_index: + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) + if(tnode->type == TEX_NODE_OUTPUT && tnode != node) + if(tnode->custom1 == index) { + index ++; + goto check_index; + } + + node->custom1 = index; +} +