GSOC 2013 paint
[blender-staging.git] / source / blender / nodes / texture / node_texture_util.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/texture/node_texture_util.c
29  *  \ingroup nodes
30  */
31
32
33 /*
34  * HOW TEXTURE NODES WORK
35  *
36  * In contrast to Shader nodes, which place a color into the output
37  * stack when executed, Texture nodes place a TexDelegate* there. To
38  * obtain a color value from this, a node further up the chain reads
39  * the TexDelegate* from its input stack, and uses tex_call_delegate to
40  * retrieve the color from the delegate.
41  *
42  * comments: (ton)
43  *
44  * This system needs recode, a node system should rely on the stack, and
45  * callbacks for nodes only should evaluate own node, not recursively go
46  * over other previous ones.
47  */
48
49 #include <assert.h>
50 #include "node_texture_util.h"
51
52
53 int tex_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
54 {
55         return STREQ(ntree->idname, "TextureNodeTree");
56 }
57
58 void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
59 {
60         node_type_base(ntype, type, name, nclass, flag);
61         
62         ntype->poll = tex_node_poll_default;
63         ntype->update_internal_links = node_update_internal_links_default;
64 }
65
66
67 static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
68 {
69         if (dg->node->need_exec) {
70                 dg->fn(out, params, dg->node, dg->in, thread);
71
72                 if (dg->cdata->do_preview)
73                         tex_do_preview(dg->preview, params->previewco, out, dg->cdata->do_manage);
74         }
75 }
76
77 static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread)
78 {
79         TexDelegate *dg = in->data;
80         if (dg) {
81                 tex_call_delegate(dg, in->vec, params, thread);
82         
83                 if (in->hasoutput && in->sockettype == SOCK_FLOAT)
84                         in->vec[1] = in->vec[2] = in->vec[0];
85         }
86         memcpy(out, in->vec, sz * sizeof(float));
87 }
88
89 void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
90 {
91         tex_input(out, 3, in, params, thread);
92 }
93
94 void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
95 {
96         tex_input(out, 4, in, params, thread);
97         
98         if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
99                 out[1] = out[2] = out[0];
100                 out[3] = 1;
101         }
102         
103         if (in->hasoutput && in->sockettype == SOCK_VECTOR) {
104                 out[0] = out[0] * 0.5f + 0.5f;
105                 out[1] = out[1] * 0.5f + 0.5f;
106                 out[2] = out[2] * 0.5f + 0.5f;
107                 out[3] = 1;
108         }
109 }
110
111 float tex_input_value(bNodeStack *in, TexParams *params, short thread)
112 {
113         float out[4];
114         tex_input_vec(out, in, params, thread);
115         return out[0];
116 }
117
118 void params_from_cdata(TexParams *out, TexCallData *in)
119 {
120         out->co = in->co;
121         out->dxt = in->dxt;
122         out->dyt = in->dyt;
123         out->previewco = in->co;
124         out->osatex = in->osatex;
125         out->cfra = in->cfra;
126         out->shi = in->shi;
127         out->mtex = in->mtex;
128 }
129
130 void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4], bool do_manage)
131 {
132         if (preview) {
133                 int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize;
134                 int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize;
135                 
136                 BKE_node_preview_set_pixel(preview, col, xs, ys, do_manage);
137         }
138 }
139
140 void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
141 {
142         TexDelegate *dg;
143         if (!out->data)
144                 /* Freed in tex_end_exec (node.c) */
145                 dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
146         else
147                 dg = out->data;
148
149         dg->cdata = cdata;
150         dg->fn = texfn;
151         dg->node = node;
152         dg->preview = execdata->preview;
153         memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
154         dg->type = out->sockettype;
155 }
156
157 void ntreeTexCheckCyclics(struct bNodeTree *ntree)
158 {
159         bNode *node;
160         for (node = ntree->nodes.first; node; node = node->next) {
161
162                 if (node->type == TEX_NODE_TEXTURE && node->id) {
163                         /* custom2 stops the node from rendering */
164                         if (node->custom1) {
165                                 node->custom2 = 1;
166                                 node->custom1 = 0;
167                         }
168                         else {
169                                 Tex *tex = (Tex *)node->id;
170                                 
171                                 node->custom2 = 0;
172                         
173                                 node->custom1 = 1;
174                                 if (tex->use_nodes && tex->nodetree) {
175                                         ntreeTexCheckCyclics(tex->nodetree);
176                                 }
177                                 node->custom1 = 0;
178                         }
179                 }
180
181         }
182 }