Initial commit. Not in build system so shouldn't interfere with anything at this...
[blender-staging.git] / source / blender / nodes / intern / CMP_nodes / CMP_curves.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2006 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "../CMP_util.h"
31
32
33 /* **************** CURVE Time  ******************** */
34
35 /* custom1 = sfra, custom2 = efra */
36 static bNodeSocketType cmp_node_time_out[]= {
37         {       SOCK_VALUE, 0, "Fac",   1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f},
38         {       -1, 0, ""       }
39 };
40
41 static void node_composit_exec_curves_time(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
42 {
43         /* stack order output: fac */
44         float fac= 0.0f;
45         
46         if(node->custom1 < node->custom2)
47                 fac= (G.scene->r.cfra - node->custom1)/(float)(node->custom2-node->custom1);
48         
49         fac= curvemapping_evaluateF(node->storage, 0, fac);
50         out[0]->vec[0]= CLAMPIS(fac, 0.0f, 1.0f);
51 }
52
53
54 static int node_composit_buts_curves_time(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
55 {
56    if(block) {
57       CurveMapping *cumap= node->storage;
58       short dx= (butr->xmax-butr->xmin)/2;
59       rctf *curvebutr;
60
61       memcpy(&curvebutr, &butr, sizeof(rctf));
62       curvebutr->ymin += 26;
63
64       curvemap_buttons(block, node->storage, 's', B_NODE_EXEC+node->nr, B_REDR, curvebutr);
65
66       cumap->flag |= CUMA_DRAW_CFRA;
67       if(node->custom1<node->custom2)
68          cumap->black[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
69
70       uiBlockBeginAlign(block);
71       uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Sta:",
72          butr->xmin, butr->ymin-22, dx, 19, 
73          &node->custom1, 1.0, 20000.0, 0, 0, "Start frame");
74       uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "End:",
75          butr->xmin+dx, butr->ymin-22, dx, 19, 
76          &node->custom2, 1.0, 20000.0, 0, 0, "End frame");
77
78    }
79
80    return node->width-NODE_DY;
81 };
82
83 static void node_composit_init_curves_time(bNode* node)
84 {
85    node->custom1= G.scene->r.sfra;
86    node->custom2= G.scene->r.efra;
87    node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
88 }
89
90 bNodeType cmp_node_curve_time= {
91         /* type code   */       CMP_NODE_TIME,
92         /* name        */       "Time",
93         /* width+range */       140, 100, 320,
94         /* class+opts  */       NODE_CLASS_INPUT, NODE_OPTIONS,
95         /* input sock  */       NULL,
96         /* output sock */       cmp_node_time_out,
97         /* storage     */       "CurveMapping",
98         /* execfunc    */       node_composit_exec_curves_time,
99    /* butfunc     */ node_composit_buts_curves_time,
100                      node_composit_init_curves_time
101 };
102
103
104
105 /* **************** CURVE VEC  ******************** */
106 static bNodeSocketType cmp_node_curve_vec_in[]= {
107         {       SOCK_VECTOR, 1, "Vector",       0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
108         {       -1, 0, ""       }
109 };
110
111 static bNodeSocketType cmp_node_curve_vec_out[]= {
112         {       SOCK_VECTOR, 0, "Vector",       0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
113         {       -1, 0, ""       }
114 };
115
116 static void node_composit_exec_curve_vec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
117 {
118         /* stack order input:  vec */
119         /* stack order output: vec */
120         
121         curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec);
122 };
123
124 static void node_composit_init_curve_vec(bNode* node)
125 {
126    node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f);
127 };
128
129 bNodeType cmp_node_curve_vec= {
130         /* type code   */       CMP_NODE_CURVE_VEC,
131         /* name        */       "Vector Curves",
132         /* width+range */       200, 140, 320,
133         /* class+opts  */       NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
134         /* input sock  */       cmp_node_curve_vec_in,
135         /* output sock */       cmp_node_curve_vec_out,
136         /* storage     */       "CurveMapping",
137         /* execfunc    */       node_composit_exec_curve_vec,
138    /* butfunc     */ node_buts_curvevec,
139                      node_composit_init_curve_vec
140         
141 };
142
143 /* **************** CURVE RGB  ******************** */
144 static bNodeSocketType cmp_node_curve_rgb_in[]= {
145         {       SOCK_VALUE, 1, "Fac",   1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
146         {       SOCK_RGBA, 1, "Image",  0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
147         {       -1, 0, ""       }
148 };
149
150 static bNodeSocketType cmp_node_curve_rgb_out[]= {
151         {       SOCK_RGBA, 0, "Image",  0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
152         {       -1, 0, ""       }
153 };
154
155 static void do_curves(bNode *node, float *out, float *in)
156 {
157         curvemapping_evaluate_premulRGBF(node->storage, out, in);
158         out[3]= in[3];
159 }
160
161 static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
162 {
163         
164         if(*fac>=1.0)
165                 curvemapping_evaluate_premulRGBF(node->storage, out, in);
166         else if(*fac<=0.0) {
167                 VECCOPY(out, in);
168         }
169         else {
170                 float col[4], mfac= 1.0f-*fac;
171                 curvemapping_evaluate_premulRGBF(node->storage, col, in);
172                 out[0]= mfac*in[0] + *fac*col[0];
173                 out[1]= mfac*in[1] + *fac*col[1];
174                 out[2]= mfac*in[2] + *fac*col[2];
175         }
176         out[3]= in[3];
177 }
178
179 static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
180 {
181         /* stack order input:  fac, image */
182         /* stack order output: image */
183         
184         if(out[0]->hasoutput==0)
185                 return;
186
187         /* input no image? then only color operation */
188         if(in[1]->data==NULL) {
189                 curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec);
190         }
191         else {
192                 /* make output size of input image */
193                 CompBuf *cbuf= in[1]->data;
194                 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
195                 
196                 if(in[0]->data)
197                         composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL);
198                 else
199                         composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
200                 
201                 out[0]->data= stackbuf;
202         }
203         
204 };
205
206 static void node_composit_init_curve_rgb(bNode* node)
207 {
208    node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
209 };
210
211 bNodeType cmp_node_curve_rgb= {
212         /* type code   */       CMP_NODE_CURVE_RGB,
213         /* name        */       "RGB Curves",
214         /* width+range */       200, 140, 320,
215         /* class+opts  */       NODE_CLASS_OP_COLOR, NODE_OPTIONS,
216         /* input sock  */       cmp_node_curve_rgb_in,
217         /* output sock */       cmp_node_curve_rgb_out,
218         /* storage     */       "CurveMapping",
219         /* execfunc    */       node_composit_exec_curve_rgb,
220    /* butfunc     */ node_buts_curvecol,
221                      node_composit_init_curve_rgb       
222 };
223