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