Merging r47874 through r47885 from trunk into soc-2011-tomato
[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 #include "COM_KeyingNode.h"
117
118 Node *Converter::convert(bNode *bNode)
119 {
120         Node * node;
121
122         if (bNode->flag & NODE_MUTED) {
123                 node = new MuteNode(bNode);
124                 return node;
125         }
126
127         switch (bNode->type) {
128         case CMP_NODE_COMPOSITE:
129                 node = new CompositorNode(bNode);
130                 break;
131         case CMP_NODE_R_LAYERS:
132                 node = new RenderLayersNode(bNode);
133                 break;
134         case CMP_NODE_TEXTURE:
135                 node = new TextureNode(bNode);
136                 break;
137         case CMP_NODE_RGBTOBW:
138                 node = new ColourToBWNode(bNode);
139                 break;
140         case CMP_NODE_MIX_RGB:
141                 node = new MixNode(bNode);
142                 break;
143         case CMP_NODE_TRANSLATE:
144                 node = new TranslateNode(bNode);
145                 break;
146         case CMP_NODE_SCALE:
147                 node = new ScaleNode(bNode);
148                 break;
149         case CMP_NODE_ROTATE:
150                 node = new RotateNode(bNode);
151                 break;
152         case CMP_NODE_FLIP:
153                 node = new FlipNode(bNode);
154                 break;
155         case CMP_NODE_FILTER:
156                 node = new FilterNode(bNode);
157                 break;
158         case CMP_NODE_ID_MASK:
159                 node = new IDMaskNode(bNode);
160                 break;
161         case CMP_NODE_BRIGHTCONTRAST:
162                 node = new BrightnessNode(bNode);
163                 break;
164         case CMP_NODE_SEPRGBA:
165                 node = new SeparateRGBANode(bNode);
166                 break;
167         case CMP_NODE_COMBRGBA:
168                 node = new CombineRGBANode(bNode);
169                 break;
170         case CMP_NODE_SEPHSVA:
171                 node = new SeparateHSVANode(bNode);
172                 break;
173         case CMP_NODE_COMBHSVA:
174                 node = new CombineHSVANode(bNode);
175                 break;
176         case CMP_NODE_SEPYUVA:
177                 node = new SeparateYUVANode(bNode);
178                 break;
179         case CMP_NODE_COMBYUVA:
180                 node = new CombineYUVANode(bNode);
181                 break;
182         case CMP_NODE_SEPYCCA:
183                 node = new SeparateYCCANode(bNode);
184                 break;
185         case CMP_NODE_COMBYCCA:
186                 node = new CombineYCCANode(bNode);
187                 break;
188         case CMP_NODE_ALPHAOVER:
189                 node = new AlphaOverNode(bNode);
190                 break;
191         case CMP_NODE_COLORBALANCE:
192                 node = new ColorBalanceNode(bNode);
193                 break;
194         case CMP_NODE_VIEWER:
195                 node = new ViewerNode(bNode);
196                 break;
197         case CMP_NODE_SPLITVIEWER:
198                 node = new SplitViewerNode(bNode);
199                 break;
200         case CMP_NODE_INVERT:
201                 node = new InvertNode(bNode);
202                 break;
203         case NODE_GROUP:
204                 node = new GroupNode(bNode);
205                 break;
206         case CMP_NODE_NORMAL:
207                 node = new NormalNode(bNode);
208                 break;
209         case CMP_NODE_NORMALIZE:
210                 node = new NormalizeNode(bNode);
211                 break;
212         case CMP_NODE_IMAGE:
213                 node = new ImageNode(bNode);
214                 break;
215         case CMP_NODE_SETALPHA:
216                 node = new SetAlphaNode(bNode);
217                 break;
218         case CMP_NODE_PREMULKEY:
219                 node = new ConvertAlphaNode(bNode);
220                 break;
221         case CMP_NODE_MATH:
222                 node = new MathNode(bNode);
223                 break;
224         case CMP_NODE_HUE_SAT:
225                 node = new HueSaturationValueNode(bNode);
226                 break;
227         case CMP_NODE_COLORCORRECTION:
228                 node = new ColorCorrectionNode(bNode);
229                 break;
230         case CMP_NODE_MASK_BOX:
231                 node = new BoxMaskNode(bNode);
232                 break;
233         case CMP_NODE_MASK_ELLIPSE:
234                 node = new EllipseMaskNode(bNode);
235                 break;
236         case CMP_NODE_GAMMA:
237                 node = new GammaNode(bNode);
238                 break;
239         case CMP_NODE_CURVE_RGB:
240                 node = new ColorCurveNode(bNode);
241                 break;
242         case CMP_NODE_CURVE_VEC:
243                 node = new VectorCurveNode(bNode);
244                 break;
245         case CMP_NODE_HUECORRECT:
246                 node = new HueSaturationValueCorrectNode(bNode);
247                 break;
248         case CMP_NODE_MAP_UV:
249                 node = new MapUVNode(bNode);
250                 break;
251         case CMP_NODE_DISPLACE:
252                 node = new DisplaceNode(bNode);
253                 break;
254         case CMP_NODE_VALTORGB:
255                 node = new ColorRampNode(bNode);
256                 break;
257         case CMP_NODE_DIFF_MATTE:
258                 node = new DifferenceMatteNode(bNode);
259                 break;
260         case CMP_NODE_LUMA_MATTE:
261                 node = new LuminanceMatteNode(bNode);
262                 break;
263         case CMP_NODE_DIST_MATTE:
264                 node = new DistanceMatteNode(bNode);
265                 break;
266         case CMP_NODE_CHROMA_MATTE:
267                 node = new ChromaMatteNode(bNode);
268                 break;
269         case CMP_NODE_COLOR_MATTE:
270                 node = new ColorMatteNode(bNode);
271                 break;
272         case CMP_NODE_CHANNEL_MATTE:
273                 node = new ChannelMatteNode(bNode);
274                 break;
275         case CMP_NODE_BLUR:
276                 node = new BlurNode(bNode);
277                 break;
278         case CMP_NODE_BOKEHIMAGE:
279                 node = new BokehImageNode(bNode);
280                 break;
281         case CMP_NODE_BOKEHBLUR:
282                 node = new BokehBlurNode(bNode);
283                 break;
284         case CMP_NODE_DILATEERODE:
285                 node = new DilateErodeNode(bNode);
286                 break;
287         case CMP_NODE_LENSDIST:
288                 node = new LensDistortionNode(bNode);
289                 break;
290         case CMP_NODE_RGB:
291                 node = new ColorNode(bNode);
292                 break;
293         case CMP_NODE_VALUE:
294                 node = new ValueNode(bNode);
295                 break;
296         case CMP_NODE_TIME:
297                 node = new TimeNode(bNode);
298                 break;
299         case CMP_NODE_DBLUR:
300                 node = new DirectionalBlurNode(bNode);
301                 break;
302         case CMP_NODE_ZCOMBINE:
303                 node = new ZCombineNode(bNode);
304                 break;
305         case CMP_NODE_TONEMAP:
306                 node = new TonemapNode(bNode);
307                 break;
308         case CMP_NODE_SWITCH:
309                 node = new SwitchNode(bNode);
310                 break;
311         case CMP_NODE_GLARE:
312                 node = new GlareNode(bNode);
313                 break;
314         case CMP_NODE_MOVIECLIP:
315                 node = new MovieClipNode(bNode);
316                 break;
317         case CMP_NODE_COLOR_SPILL:
318                 node = new ColorSpillNode(bNode);
319                 break;
320 case CMP_NODE_OUTPUT_FILE:
321                 node = new OutputFileNode(bNode);
322                 break;
323         case CMP_NODE_MAP_VALUE:
324                 node = new MapValueNode(bNode);
325                 break;
326         case CMP_NODE_TRANSFORM:
327                 node = new TransformNode(bNode);
328                 break;
329         case CMP_NODE_STABILIZE2D:
330                 node = new Stabilize2dNode(bNode);
331                 break;
332         case CMP_NODE_BILATERALBLUR:
333                 node = new BilateralBlurNode(bNode);
334                 break;
335         case CMP_NODE_VECBLUR:
336                 node = new VectorBlurNode(bNode);
337                 break;
338         case CMP_NODE_MOVIEDISTORTION:
339                 node = new MovieDistortionNode(bNode);
340                 break;
341         case CMP_NODE_VIEW_LEVELS:
342                 node = new ViewLevelsNode(bNode);
343                 break;
344         case CMP_NODE_DEFOCUS:
345                 node = new DefocusNode(bNode);
346                 break;
347         case CMP_NODE_DOUBLEEDGEMASK:
348                 node = new DoubleEdgeMaskNode(bNode);
349                 break;
350         case CMP_NODE_CROP:
351                 node = new CropNode(bNode);
352                 break;
353         case CMP_NODE_MASK:
354                 node = new MaskNode(bNode);
355                 break;
356         case CMP_NODE_KEYINGSCREEN:
357                 node = new KeyingScreenNode(bNode);
358                 break;
359         case CMP_NODE_KEYING:
360                 node = new KeyingNode(bNode);
361                 break;
362         /* not inplemented yet */
363         default:
364                 node = new MuteNode(bNode);
365                 break;
366         }
367         return node;
368 }
369 void Converter::convertDataType(SocketConnection *connection, ExecutionSystem *system)
370 {
371         OutputSocket *outputSocket = connection->getFromSocket();
372         InputSocket *inputSocket = connection->getToSocket();
373         DataType fromDatatype = outputSocket->getDataType();
374         DataType toDatatype = inputSocket->getDataType();
375         NodeOperation * converter = NULL;
376         if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
377                 converter = new ConvertValueToColourProg();
378         }
379         else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
380                 converter = new ConvertValueToVectorOperation();
381         }
382         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
383                 converter = new ConvertColourToValueProg();
384         }
385         else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
386                 converter = new ConvertColorToVectorOperation();
387         }
388         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
389                 converter = new ConvertVectorToValueOperation();
390         }
391         else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
392                 converter = new ConvertVectorToColorOperation();
393         }
394         if (converter != NULL) {
395                 inputSocket->relinkConnections(converter->getInputSocket(0));
396                 ExecutionSystemHelper::addLink(system->getConnections(), converter->getOutputSocket(), inputSocket);
397                 system->addOperation(converter);
398         }
399 }
400
401 void Converter::convertResolution(SocketConnection *connection, ExecutionSystem *system)
402 {
403         InputSocketResizeMode mode = connection->getToSocket()->getResizeMode();
404
405         NodeOperation * toOperation = (NodeOperation*)connection->getToNode();
406         const float toWidth = toOperation->getWidth();
407         const float toHeight = toOperation->getHeight();
408         NodeOperation * fromOperation = (NodeOperation*)connection->getFromNode();
409         const float fromWidth = fromOperation->getWidth();
410         const float fromHeight = fromOperation->getHeight();
411         bool doCenter = false;
412         bool doScale = false;
413         float addX=     (toWidth-fromWidth)/2.0f;
414         float addY = (toHeight-fromHeight)/2.0f;
415         float scaleX=0;
416         float scaleY=0;
417
418         switch (mode) {
419         case COM_SC_NO_RESIZE:
420                 break;
421         case COM_SC_CENTER:
422                 doCenter = true;
423                 break;
424         case COM_SC_FIT_WIDTH:
425                 doCenter = true;
426                 doScale = true;
427                 scaleX = scaleY = toWidth/fromWidth;
428                 break;
429         case COM_SC_FIT_HEIGHT:
430                 doCenter = true;
431                 doScale = true;
432                 scaleX = scaleY = toHeight/fromHeight;
433                 break;
434         case COM_SC_FIT:
435                 doCenter = true;
436                 doScale = true;
437                 scaleX = toWidth/fromWidth;
438                 scaleY = toHeight/fromHeight;
439                 if (scaleX < scaleY) {
440                         scaleX = scaleY;
441                 }
442                 else {
443                         scaleY = scaleX;
444                 }
445                 break;
446         case COM_SC_STRETCH:
447                 doCenter = true;
448                 doScale = true;
449                 scaleX = toWidth/fromWidth;
450                 scaleY = toHeight/fromHeight;
451                 break;
452
453         }
454
455         if (doCenter) {
456                 NodeOperation *first = NULL;
457                 SocketConnection *c;
458                 ScaleOperation * scaleOperation = NULL;
459                 if (doScale) {
460                         scaleOperation = new ScaleOperation();
461                         first = scaleOperation;
462                         SetValueOperation * sxop = new SetValueOperation();
463                         sxop->setValue(scaleX);
464                         c = ExecutionSystemHelper::addLink(system->getConnections(), sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
465                         c->setIgnoreResizeCheck(true);
466                         SetValueOperation * syop = new SetValueOperation();
467                         syop->setValue(scaleY);
468                         c = ExecutionSystemHelper::addLink(system->getConnections(), syop->getOutputSocket(), scaleOperation->getInputSocket(2));
469                         c->setIgnoreResizeCheck(true);
470                         system->addOperation(sxop);
471                         system->addOperation(syop);
472
473                         unsigned int resolution[2] = {fromWidth, fromHeight};
474                         scaleOperation->setResolution(resolution);
475                         sxop->setResolution(resolution);
476                         syop->setResolution(resolution);
477                         system->addOperation(scaleOperation);
478
479                         c->setIgnoreResizeCheck(true);
480                 }
481
482                 TranslateOperation * translateOperation = new TranslateOperation();
483                 if (!first) first = translateOperation;
484                 SetValueOperation * xop = new SetValueOperation();
485                 xop->setValue(addX);
486                 c = ExecutionSystemHelper::addLink(system->getConnections(), xop->getOutputSocket(), translateOperation->getInputSocket(1));
487                 c->setIgnoreResizeCheck(true);
488                 SetValueOperation * yop = new SetValueOperation();
489                 yop->setValue(addY);
490                 c = ExecutionSystemHelper::addLink(system->getConnections(), yop->getOutputSocket(), translateOperation->getInputSocket(2));
491                 c->setIgnoreResizeCheck(true);
492                 system->addOperation(xop);
493                 system->addOperation(yop);
494
495                 unsigned int resolution[2] = {toWidth, toHeight};
496                 translateOperation->setResolution(resolution);
497                 xop->setResolution(resolution);
498                 yop->setResolution(resolution);
499                 system->addOperation(translateOperation);
500
501                 if (doScale) {
502                         c = ExecutionSystemHelper::addLink(system->getConnections(), scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
503                         c->setIgnoreResizeCheck(true);
504                 }
505
506                 InputSocket * inputSocket = connection->getToSocket();
507                 inputSocket->relinkConnections(first->getInputSocket(0));
508                 c = ExecutionSystemHelper::addLink(system->getConnections(), translateOperation->getOutputSocket(), inputSocket);
509                 c->setIgnoreResizeCheck(true);
510         }
511
512         connection->setIgnoreResizeCheck(true);
513 }