Keying Screen node from tomato branch
[blender.git] / source / blender / compositor / intern / COM_Converter.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
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  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include "COM_Converter.h"
24 #include "BKE_node.h"
25 #include "COM_CompositorNode.h"
26 #include "COM_RenderLayersNode.h"
27 #include "COM_ColorToBWNode.h"
28 #include "string.h"
29 #include "COM_SocketConnection.h"
30 #include "COM_ConvertColourToValueProg.h"
31 #include "COM_ConvertValueToColourProg.h"
32 #include "COM_ConvertColorToVectorOperation.h"
33 #include "COM_ConvertValueToVectorOperation.h"
34 #include "COM_ConvertVectorToColorOperation.h"
35 #include "COM_ConvertVectorToValueOperation.h"
36 #include "COM_ExecutionSystem.h"
37 #include "COM_MixNode.h"
38 #include "COM_MuteNode.h"
39 #include "COM_TranslateNode.h"
40 #include "COM_RotateNode.h"
41 #include "COM_ScaleNode.h"
42 #include "COM_FlipNode.h"
43 #include "COM_IDMaskNode.h"
44 #include "COM_FilterNode.h"
45 #include "COM_BrightnessNode.h"
46 #include "COM_SeparateRGBANode.h"
47 #include "COM_CombineRGBANode.h"
48 #include "COM_SeparateHSVANode.h"
49 #include "COM_CombineHSVANode.h"
50 #include "COM_SeparateYUVANode.h"
51 #include "COM_CombineYUVANode.h"
52 #include "COM_SeparateYCCANode.h"
53 #include "COM_CombineYCCANode.h"
54 #include "COM_AlphaOverNode.h"
55 #include "COM_ColorBalanceNode.h"
56 #include "COM_ViewerNode.h"
57 #include "COM_SplitViewerNode.h"
58 #include "COM_InvertNode.h"
59 #include "COM_GroupNode.h"
60 #include "COM_NormalNode.h"
61 #include "COM_NormalizeNode.h"
62 #include "COM_ImageNode.h"
63 #include "COM_BokehImageNode.h"
64 #include "COM_ColorCurveNode.h"
65 #include "COM_VectorCurveNode.h"
66 #include "COM_SetAlphaNode.h"
67 #include "COM_ConvertAlphaNode.h"
68 #include "COM_MapUVNode.h"
69 #include "COM_DisplaceNode.h"
70 #include "COM_MathNode.h"
71 #include "COM_HueSaturationValueNode.h"
72 #include "COM_HueSaturationValueCorrectNode.h"
73 #include "COM_ColorCorrectionNode.h"
74 #include "COM_BoxMaskNode.h"
75 #include "COM_EllipseMaskNode.h"
76 #include "COM_GammaNode.h"
77 #include "COM_ColorRampNode.h"
78 #include "COM_DifferenceMatteNode.h"
79 #include "COM_LuminanceMatteNode.h"
80 #include "COM_DistanceMatteNode.h"
81 #include "COM_ChromaMatteNode.h"
82 #include "COM_ColorMatteNode.h"
83 #include "COM_ChannelMatteNode.h"
84 #include "COM_BlurNode.h"
85 #include "COM_BokehBlurNode.h"
86 #include "COM_DilateErodeNode.h"
87 #include "COM_TranslateOperation.h"
88 #include "COM_LensDistortionNode.h"
89 #include "COM_TextureNode.h"
90 #include "COM_ColorNode.h"
91 #include "COM_ValueNode.h"
92 #include "COM_TimeNode.h"
93 #include "COM_DirectionalBlurNode.h"
94 #include "COM_ZCombineNode.h"
95 #include "COM_SetValueOperation.h"
96 #include "COM_ScaleOperation.h"
97 #include "COM_ExecutionSystemHelper.h"
98 #include "COM_TonemapNode.h"
99 #include "COM_SwitchNode.h"
100 #include "COM_GlareNode.h"
101 #include "COM_MovieClipNode.h"
102 #include "COM_ColorSpillNode.h"
103 #include "COM_OutputFileNode.h"
104 #include "COM_MapValueNode.h"
105 #include "COM_TransformNode.h"
106 #include "COM_Stabilize2dNode.h"
107 #include "COM_BilateralBlurNode.h"
108 #include "COM_VectorBlurNode.h"
109 #include "COM_MovieDistortionNode.h"
110 #include "COM_ViewLevelsNode.h"
111 #include "COM_DefocusNode.h"
112 #include "COM_DoubleEdgeMaskNode.h"
113 #include "COM_CropNode.h"
114 #include "COM_MaskNode.h"
115 #include "COM_KeyingScreenNode.h"
116
117 Node *Converter::convert(bNode *bNode)
118 {
119         Node * node;
120
121         if (bNode->flag & NODE_MUTED) {
122                 node = new MuteNode(bNode);
123                 return node;
124         }
125
126         switch (bNode->type) {
127         case CMP_NODE_COMPOSITE:
128                 node = new CompositorNode(bNode);
129                 break;
130         case CMP_NODE_R_LAYERS:
131                 node = new RenderLayersNode(bNode);
132                 break;
133         case CMP_NODE_TEXTURE:
134                 node = new TextureNode(bNode);
135                 break;
136         case CMP_NODE_RGBTOBW:
137                 node = new ColourToBWNode(bNode);
138                 break;
139         case CMP_NODE_MIX_RGB:
140                 node = new MixNode(bNode);
141                 break;
142         case CMP_NODE_TRANSLATE:
143                 node = new TranslateNode(bNode);
144                 break;
145         case CMP_NODE_SCALE:
146                 node = new ScaleNode(bNode);
147                 break;
148         case CMP_NODE_ROTATE:
149                 node = new RotateNode(bNode);
150                 break;
151         case CMP_NODE_FLIP:
152                 node = new FlipNode(bNode);
153                 break;
154         case CMP_NODE_FILTER:
155                 node = new FilterNode(bNode);
156                 break;
157         case CMP_NODE_ID_MASK:
158                 node = new IDMaskNode(bNode);
159                 break;
160         case CMP_NODE_BRIGHTCONTRAST:
161                 node = new BrightnessNode(bNode);
162                 break;
163         case CMP_NODE_SEPRGBA:
164                 node = new SeparateRGBANode(bNode);
165                 break;
166         case CMP_NODE_COMBRGBA:
167                 node = new CombineRGBANode(bNode);
168                 break;
169         case CMP_NODE_SEPHSVA:
170                 node = new SeparateHSVANode(bNode);
171                 break;
172         case CMP_NODE_COMBHSVA:
173                 node = new CombineHSVANode(bNode);
174                 break;
175         case CMP_NODE_SEPYUVA:
176                 node = new SeparateYUVANode(bNode);
177                 break;
178         case CMP_NODE_COMBYUVA:
179                 node = new CombineYUVANode(bNode);
180                 break;
181         case CMP_NODE_SEPYCCA:
182                 node = new SeparateYCCANode(bNode);
183                 break;
184         case CMP_NODE_COMBYCCA:
185                 node = new CombineYCCANode(bNode);
186                 break;
187         case CMP_NODE_ALPHAOVER:
188                 node = new AlphaOverNode(bNode);
189                 break;
190         case CMP_NODE_COLORBALANCE:
191                 node = new ColorBalanceNode(bNode);
192                 break;
193         case CMP_NODE_VIEWER:
194                 node = new ViewerNode(bNode);
195                 break;
196         case CMP_NODE_SPLITVIEWER:
197                 node = new SplitViewerNode(bNode);
198                 break;
199         case CMP_NODE_INVERT:
200                 node = new InvertNode(bNode);
201                 break;
202         case NODE_GROUP:
203                 node = new GroupNode(bNode);
204                 break;
205         case CMP_NODE_NORMAL:
206                 node = new NormalNode(bNode);
207                 break;
208         case CMP_NODE_NORMALIZE:
209                 node = new NormalizeNode(bNode);
210                 break;
211         case CMP_NODE_IMAGE:
212                 node = new ImageNode(bNode);
213                 break;
214         case CMP_NODE_SETALPHA:
215                 node = new SetAlphaNode(bNode);
216                 break;
217         case CMP_NODE_PREMULKEY:
218                 node = new ConvertAlphaNode(bNode);
219                 break;
220         case CMP_NODE_MATH:
221                 node = new MathNode(bNode);
222                 break;
223         case CMP_NODE_HUE_SAT:
224                 node = new HueSaturationValueNode(bNode);
225                 break;
226         case CMP_NODE_COLORCORRECTION:
227                 node = new ColorCorrectionNode(bNode);
228                 break;
229         case CMP_NODE_MASK_BOX:
230                 node = new BoxMaskNode(bNode);
231                 break;
232         case CMP_NODE_MASK_ELLIPSE:
233                 node = new EllipseMaskNode(bNode);
234                 break;
235         case CMP_NODE_GAMMA:
236                 node = new GammaNode(bNode);
237                 break;
238         case CMP_NODE_CURVE_RGB:
239                 node = new ColorCurveNode(bNode);
240                 break;
241         case CMP_NODE_CURVE_VEC:
242                 node = new VectorCurveNode(bNode);
243                 break;
244         case CMP_NODE_HUECORRECT:
245                 node = new HueSaturationValueCorrectNode(bNode);
246                 break;
247         case CMP_NODE_MAP_UV:
248                 node = new MapUVNode(bNode);
249                 break;
250         case CMP_NODE_DISPLACE:
251                 node = new DisplaceNode(bNode);
252                 break;
253         case CMP_NODE_VALTORGB:
254                 node = new ColorRampNode(bNode);
255                 break;
256         case CMP_NODE_DIFF_MATTE:
257                 node = new DifferenceMatteNode(bNode);
258                 break;
259         case CMP_NODE_LUMA_MATTE:
260                 node = new LuminanceMatteNode(bNode);
261                 break;
262         case CMP_NODE_DIST_MATTE:
263                 node = new DistanceMatteNode(bNode);
264                 break;
265         case CMP_NODE_CHROMA_MATTE:
266                 node = new ChromaMatteNode(bNode);
267                 break;
268         case CMP_NODE_COLOR_MATTE:
269                 node = new ColorMatteNode(bNode);
270                 break;
271         case CMP_NODE_CHANNEL_MATTE:
272                 node = new ChannelMatteNode(bNode);
273                 break;
274         case CMP_NODE_BLUR:
275                 node = new BlurNode(bNode);
276                 break;
277         case CMP_NODE_BOKEHIMAGE:
278                 node = new BokehImageNode(bNode);
279                 break;
280         case CMP_NODE_BOKEHBLUR:
281                 node = new BokehBlurNode(bNode);
282                 break;
283         case CMP_NODE_DILATEERODE:
284                 node = new DilateErodeNode(bNode);
285                 break;
286         case CMP_NODE_LENSDIST:
287                 node = new LensDistortionNode(bNode);
288                 break;
289         case CMP_NODE_RGB:
290                 node = new ColorNode(bNode);
291                 break;
292         case CMP_NODE_VALUE:
293                 node = new ValueNode(bNode);
294                 break;
295         case CMP_NODE_TIME:
296                 node = new TimeNode(bNode);
297                 break;
298         case CMP_NODE_DBLUR:
299                 node = new DirectionalBlurNode(bNode);
300                 break;
301         case CMP_NODE_ZCOMBINE:
302                 node = new ZCombineNode(bNode);
303                 break;
304         case CMP_NODE_TONEMAP:
305                 node = new TonemapNode(bNode);
306                 break;
307         case CMP_NODE_SWITCH:
308                 node = new SwitchNode(bNode);
309                 break;
310         case CMP_NODE_GLARE:
311                 node = new GlareNode(bNode);
312                 break;
313         case CMP_NODE_MOVIECLIP:
314                 node = new MovieClipNode(bNode);
315                 break;
316         case CMP_NODE_COLOR_SPILL:
317                 node = new ColorSpillNode(bNode);
318                 break;
319 case CMP_NODE_OUTPUT_FILE:
320                 node = new OutputFileNode(bNode);
321                 break;
322         case CMP_NODE_MAP_VALUE:
323                 node = new MapValueNode(bNode);
324                 break;
325         case CMP_NODE_TRANSFORM:
326                 node = new TransformNode(bNode);
327                 break;
328         case CMP_NODE_STABILIZE2D:
329                 node = new Stabilize2dNode(bNode);
330                 break;
331         case CMP_NODE_BILATERALBLUR:
332                 node = new BilateralBlurNode(bNode);
333                 break;
334         case CMP_NODE_VECBLUR:
335                 node = new VectorBlurNode(bNode);
336                 break;
337         case CMP_NODE_MOVIEDISTORTION:
338                 node = new MovieDistortionNode(bNode);
339                 break;
340         case CMP_NODE_VIEW_LEVELS:
341                 node = new ViewLevelsNode(bNode);
342                 break;
343         case CMP_NODE_DEFOCUS:
344                 node = new DefocusNode(bNode);
345                 break;
346         case CMP_NODE_DOUBLEEDGEMASK:
347                 node = new DoubleEdgeMaskNode(bNode);
348                 break;
349         case CMP_NODE_CROP:
350                 node = new CropNode(bNode);
351                 break;
352         case CMP_NODE_MASK:
353                 node = new MaskNode(bNode);
354                 break;
355         case CMP_NODE_KEYINGSCREEN:
356                 node = new KeyingScreenNode(bNode);
357                 break;
358         /* not inplemented yet */
359         default:
360                 node = new MuteNode(bNode);
361                 break;
362         }
363         return node;
364 }
365 void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *system)
366 {
367         OutputSocket *outputSocket = connection->getFromSocket();
368         InputSocket *inputSocket = connection->getToSocket();
369         DataType fromDatatype = outputSocket->getDataType();
370         DataType toDatatype = inputSocket->getDataType();
371         NodeOperation * converter = NULL;
372         if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
373                 converter = new ConvertValueToColourProg();
374         }
375         else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
376                 converter = new ConvertValueToVectorOperation();
377         }
378         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
379                 converter = new ConvertColourToValueProg();
380         }
381         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
382                 converter = new ConvertColorToVectorOperation();
383         }
384         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
385                 converter = new ConvertVectorToValueOperation();
386         }
387         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
388                 converter = new ConvertVectorToColorOperation();
389         }
390         if (converter != NULL) {
391                 inputSocket->relinkConnections(converter->getInputSocket(0));
392                 ExecutionSystemHelper::addLink(system->getConnections(), converter->getOutputSocket(), inputSocket);
393                 system->addOperation(converter);
394         }
395 }
396
397 void Converter::convertResolution(SocketConnection *connection, ExecutionSystem *system)
398 {
399         InputSocketResizeMode mode = connection->getToSocket()->getResizeMode();
400
401         NodeOperation * toOperation = (NodeOperation*)connection->getToNode();
402         const float toWidth = toOperation->getWidth();
403         const float toHeight = toOperation->getHeight();
404         NodeOperation * fromOperation = (NodeOperation*)connection->getFromNode();
405         const float fromWidth = fromOperation->getWidth();
406         const float fromHeight = fromOperation->getHeight();
407         bool doCenter = false;
408         bool doScale = false;
409         float addX=     (toWidth-fromWidth)/2.0f;
410         float addY = (toHeight-fromHeight)/2.0f;
411         float scaleX=0;
412         float scaleY=0;
413
414         switch (mode) {
415         case COM_SC_NO_RESIZE:
416                 break;
417         case COM_SC_CENTER:
418                 doCenter = true;
419                 break;
420         case COM_SC_FIT_WIDTH:
421                 doCenter = true;
422                 doScale = true;
423                 scaleX = scaleY = toWidth/fromWidth;
424                 break;
425         case COM_SC_FIT_HEIGHT:
426                 doCenter = true;
427                 doScale = true;
428                 scaleX = scaleY = toHeight/fromHeight;
429                 break;
430         case COM_SC_FIT:
431                 doCenter = true;
432                 doScale = true;
433                 scaleX = toWidth/fromWidth;
434                 scaleY = toHeight/fromHeight;
435                 if (scaleX < scaleY) {
436                         scaleX = scaleY;
437                 }
438                 else {
439                         scaleY = scaleX;
440                 }
441                 break;
442         case COM_SC_STRETCH:
443                 doCenter = true;
444                 doScale = true;
445                 scaleX = toWidth/fromWidth;
446                 scaleY = toHeight/fromHeight;
447                 break;
448
449         }
450
451         if (doCenter) {
452                 NodeOperation *first = NULL;
453                 SocketConnection *c;
454                 ScaleOperation * scaleOperation = NULL;
455                 if (doScale) {
456                         scaleOperation = new ScaleOperation();
457                         first = scaleOperation;
458                         SetValueOperation * sxop = new SetValueOperation();
459                         sxop->setValue(scaleX);
460                         c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
461                         c->setIgnoreResizeCheck(true);
462                         SetValueOperation * syop = new SetValueOperation();
463                         syop->setValue(scaleY);
464                         c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2));
465                         c->setIgnoreResizeCheck(true);
466                         system->addOperation(sxop);
467                         system->addOperation(syop);
468
469                         unsigned int resolution[2] = {fromWidth, fromHeight};
470                         scaleOperation->setResolution(resolution);
471                         sxop->setResolution(resolution);
472                         syop->setResolution(resolution);
473                         system->addOperation(scaleOperation);
474
475                         c->setIgnoreResizeCheck(true);
476                 }
477
478                 TranslateOperation * translateOperation = new TranslateOperation();
479                 if (!first) first = translateOperation;
480                 SetValueOperation * xop = new SetValueOperation();
481                 xop->setValue(addX);
482                 c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1));
483                 c->setIgnoreResizeCheck(true);
484                 SetValueOperation * yop = new SetValueOperation();
485                 yop->setValue(addY);
486                 c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2));
487                 c->setIgnoreResizeCheck(true);
488                 system->addOperation(xop);
489                 system->addOperation(yop);
490
491                 unsigned int resolution[2] = {toWidth, toHeight};
492                 translateOperation->setResolution(resolution);
493                 xop->setResolution(resolution);
494                 yop->setResolution(resolution);
495                 system->addOperation(translateOperation);
496
497                 if (doScale) {
498                         c = ExecutionSystemHelper::addLink(system->getConnections(), scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
499                         c->setIgnoreResizeCheck(true);
500                 }
501
502                 InputSocket * inputSocket = connection->getToSocket();
503                 inputSocket->relinkConnections(first->getInputSocket(0));
504                 c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket);
505                 c->setIgnoreResizeCheck(true);
506         }
507
508         connection->setIgnoreResizeCheck(true);
509 }