Remove ifdef-ed code, it's still in SVn anyway.
[blender.git] / source / blender / compositor / operations / COM_MapUVOperation.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  *              Dalai Felinto
20  */
21
22 #include "COM_MapUVOperation.h"
23 #include "BLI_math.h"
24
25 MapUVOperation::MapUVOperation() : NodeOperation()
26 {
27         this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
28         this->addInputSocket(COM_DT_VECTOR);
29         this->addOutputSocket(COM_DT_COLOR);
30         this->m_alpha = 0.0f;
31         this->setComplex(true);
32
33         this->m_inputUVProgram = NULL;
34         this->m_inputColorProgram = NULL;
35 }
36
37 void MapUVOperation::initExecution()
38 {
39         this->m_inputColorProgram = this->getInputSocketReader(0);
40         this->m_inputUVProgram = this->getInputSocketReader(1);
41 }
42
43 void MapUVOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
44 {
45         float inputUV[4];
46         float uv_a[4], uv_b[4];
47         float u, v;
48
49         float dx, dy;
50         float uv_l, uv_r;
51         float uv_u, uv_d;
52
53         this->m_inputUVProgram->read(inputUV, x, y, sampler);
54         if (inputUV[2] == 0.f) {
55                 zero_v4(output);
56                 return;
57         }
58         /* adaptive sampling, red (U) channel */
59         this->m_inputUVProgram->read(uv_a, x - 1, y, COM_PS_NEAREST);
60         this->m_inputUVProgram->read(uv_b, x + 1, y, COM_PS_NEAREST);
61         uv_l = uv_a[2] != 0.f ? fabsf(inputUV[0] - uv_a[0]) : 0.f;
62         uv_r = uv_b[2] != 0.f ? fabsf(inputUV[0] - uv_b[0]) : 0.f;
63
64         dx = 0.5f * (uv_l + uv_r);
65
66         /* adaptive sampling, green (V) channel */
67         this->m_inputUVProgram->read(uv_a, x, y - 1, COM_PS_NEAREST);
68         this->m_inputUVProgram->read(uv_b, x, y + 1, COM_PS_NEAREST);
69         uv_u = uv_a[2] != 0.f ? fabsf(inputUV[1] - uv_a[1]) : 0.f;
70         uv_d = uv_b[2] != 0.f ? fabsf(inputUV[1] - uv_b[1]) : 0.f;
71
72         dy = 0.5f * (uv_u + uv_d);
73
74         /* UV to alpha threshold */
75         const float threshold = this->m_alpha * 0.05f;
76         float alpha = 1.0f - threshold * (dx + dy);
77         if (alpha < 0.f) alpha = 0.f;
78         else alpha *= inputUV[2];
79
80         /* EWA filtering */
81         u = inputUV[0] * this->m_inputColorProgram->getWidth();
82         v = inputUV[1] * this->m_inputColorProgram->getHeight();
83
84         this->m_inputColorProgram->read(output, u, v, dx, dy, COM_PS_NEAREST);
85
86         /* "premul" */
87         if (alpha < 1.0f) {
88                 mul_v4_fl(output, alpha);
89         }
90 }
91
92 void MapUVOperation::deinitExecution()
93 {
94         this->m_inputUVProgram = NULL;
95         this->m_inputColorProgram = NULL;
96 }
97
98 bool MapUVOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
99 {
100         rcti colorInput;
101         rcti uvInput;
102         NodeOperation *operation = NULL;
103
104         /* the uv buffer only needs a 3x3 buffer. The image needs whole buffer */
105
106         operation = getInputOperation(0);
107         colorInput.xmax = operation->getWidth();
108         colorInput.xmin = 0;
109         colorInput.ymax = operation->getHeight();
110         colorInput.ymin = 0;
111         if (operation->determineDependingAreaOfInterest(&colorInput, readOperation, output)) {
112                 return true;
113         }
114
115         operation = getInputOperation(1);
116         uvInput.xmax = input->xmax + 1;
117         uvInput.xmin = input->xmin - 1;
118         uvInput.ymax = input->ymax + 1;
119         uvInput.ymin = input->ymin - 1;
120         if (operation->determineDependingAreaOfInterest(&uvInput, readOperation, output)) {
121                 return true;
122         }
123
124         return false;
125 }
126