Cleanup: comment blocks
[blender.git] / source / blender / compositor / operations / COM_MaskOperation.cpp
1 /*
2  * Copyright 2012, 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  *              Sergey Sharybin
22  */
23
24 #include "COM_MaskOperation.h"
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30
31 extern "C" {
32 #  include "BKE_mask.h"
33 }
34
35 MaskOperation::MaskOperation() : NodeOperation()
36 {
37         this->addOutputSocket(COM_DT_VALUE);
38         this->m_mask = NULL;
39         this->m_maskWidth = 0;
40         this->m_maskHeight = 0;
41         this->m_maskWidthInv = 0.0f;
42         this->m_maskHeightInv = 0.0f;
43         this->m_frame_shutter = 0.0f;
44         this->m_frame_number = 0;
45         this->m_rasterMaskHandleTot = 1;
46         memset(this->m_rasterMaskHandles, 0, sizeof(this->m_rasterMaskHandles));
47 }
48
49 void MaskOperation::initExecution()
50 {
51         if (this->m_mask && this->m_rasterMaskHandles[0] == NULL) {
52                 if (this->m_rasterMaskHandleTot == 1) {
53                         this->m_rasterMaskHandles[0] = BKE_maskrasterize_handle_new();
54
55                         BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[0], this->m_mask,
56                                 this->m_maskWidth, this->m_maskHeight,
57                                 true, this->m_do_smooth, this->m_do_feather);
58                 }
59                 else {
60                         /* make a throw away copy of the mask */
61                         const float frame = (float)this->m_frame_number - this->m_frame_shutter;
62                         const float frame_step = (this->m_frame_shutter * 2.0f) / this->m_rasterMaskHandleTot;
63                         float frame_iter = frame;
64
65                         Mask *mask_temp;
66
67                         mask_temp = BKE_mask_copy_nolib(this->m_mask);
68
69                         /* trick so we can get unkeyed edits to display */
70                         {
71                                 MaskLayer *masklay;
72                                 MaskLayerShape *masklay_shape;
73
74                                 for (masklay = (MaskLayer *)mask_temp->masklayers.first;
75                                      masklay;
76                                      masklay = masklay->next)
77                                 {
78                                         masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, this->m_frame_number);
79                                         BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
80                                 }
81                         }
82
83                         for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) {
84                                 this->m_rasterMaskHandles[i] = BKE_maskrasterize_handle_new();
85
86                                 /* re-eval frame info */
87                                 BKE_mask_evaluate(mask_temp, frame_iter, true);
88
89                                 BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[i], mask_temp,
90                                                               this->m_maskWidth, this->m_maskHeight,
91                                                               true, this->m_do_smooth, this->m_do_feather);
92
93                                 frame_iter += frame_step;
94                         }
95
96                         BKE_mask_free(mask_temp);
97                         MEM_freeN(mask_temp);
98                 }
99         }
100 }
101
102 void MaskOperation::deinitExecution()
103 {
104         for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) {
105                 if (this->m_rasterMaskHandles[i]) {
106                         BKE_maskrasterize_handle_free(this->m_rasterMaskHandles[i]);
107                         this->m_rasterMaskHandles[i] = NULL;
108                 }
109         }
110 }
111
112 void MaskOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
113 {
114         if (this->m_maskWidth == 0 || this->m_maskHeight == 0) {
115                 NodeOperation::determineResolution(resolution, preferredResolution);
116         }
117         else {
118                 unsigned int nr[2];
119
120                 nr[0] = this->m_maskWidth;
121                 nr[1] = this->m_maskHeight;
122
123                 NodeOperation::determineResolution(resolution, nr);
124
125                 resolution[0] = this->m_maskWidth;
126                 resolution[1] = this->m_maskHeight;
127         }
128 }
129
130 void MaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
131 {
132         const float xy[2] = {
133             (x * this->m_maskWidthInv)  + this->m_mask_px_ofs[0],
134             (y * this->m_maskHeightInv) + this->m_mask_px_ofs[1]};
135
136         if (this->m_rasterMaskHandleTot == 1) {
137                 if (this->m_rasterMaskHandles[0]) {
138                         output[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[0], xy);
139                 }
140                 else {
141                         output[0] = 0.0f;
142                 }
143         }
144         else {
145                 /* incase loop below fails */
146                 output[0] = 0.0f;
147
148                 for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) {
149                         if (this->m_rasterMaskHandles[i]) {
150                                 output[0] += BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[i], xy);
151                         }
152                 }
153
154                 /* until we get better falloff */
155                 output[0] /= this->m_rasterMaskHandleTot;
156         }
157 }