Blender V4.3
COM_BlurBaseOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7
8#include "RE_pipeline.h"
9
10namespace blender::compositor {
11
13{
14 /* data_type is almost always DataType::Color except for alpha-blur */
15 this->add_input_socket(data_type);
17 this->add_output_socket(data_type);
19 memset(&data_, 0, sizeof(NodeBlurData));
20 size_ = 1.0f;
21 sizeavailable_ = false;
22 extend_bounds_ = false;
23 use_variable_size_ = false;
24}
25
27{
29
32 if (data_.relative) {
33 int sizex, sizey;
34 switch (data_.aspect) {
36 sizex = sizey = data_.image_in_width;
37 break;
39 sizex = sizey = data_.image_in_height;
40 break;
41 default:
43 sizex = data_.image_in_width;
44 sizey = data_.image_in_height;
45 break;
46 }
47 data_.sizex = round_fl_to_int(data_.percentx * 0.01f * sizex);
48 data_.sizey = round_fl_to_int(data_.percenty * 0.01f * sizey);
49 }
50}
51
52float *BlurBaseOperation::make_gausstab(float rad, int size)
53{
54 float *gausstab, sum, val;
55 int i, n;
56
57 n = 2 * size + 1;
58
59 gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
60
61 sum = 0.0f;
62 float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
63 for (i = -size; i <= size; i++) {
64 val = RE_filter_value(data_.filtertype, float(i) * fac);
65 sum += val;
66 gausstab[i + size] = val;
67 }
68
69 sum = 1.0f / sum;
70 for (i = 0; i < n; i++) {
71 gausstab[i] *= sum;
72 }
73
74 return gausstab;
75}
76
77#if BLI_HAVE_SSE2
78__m128 *BlurBaseOperation::convert_gausstab_sse(const float *gausstab, int size)
79{
80 int n = 2 * size + 1;
81 __m128 *gausstab_sse = (__m128 *)MEM_mallocN_aligned(sizeof(__m128) * n, 16, "gausstab sse");
82 for (int i = 0; i < n; i++) {
83 gausstab_sse[i] = _mm_set1_ps(gausstab[i]);
84 }
85 return gausstab_sse;
86}
87#endif
88
89float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff)
90{
91 float *dist_fac_invert, val;
92 int i, n;
93
94 n = 2 * size + 1;
95
96 dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__);
97
98 float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
99 for (i = -size; i <= size; i++) {
100 val = 1.0f - fabsf(float(i) * fac);
101
102 /* keep in sync with rna_enum_proportional_falloff_curve_only_items */
103 switch (falloff) {
104 case PROP_SMOOTH:
105 /* ease - gives less hard lines for dilate/erode feather */
106 val = (3.0f * val * val - 2.0f * val * val * val);
107 break;
108 case PROP_SPHERE:
109 val = sqrtf(2.0f * val - val * val);
110 break;
111 case PROP_ROOT:
112 val = sqrtf(val);
113 break;
114 case PROP_SHARP:
115 val = val * val;
116 break;
117 case PROP_INVSQUARE:
118 val = val * (2.0f - val);
119 break;
120 case PROP_LIN:
121 /* nothing to do */
122 break;
123#ifndef NDEBUG
124 case -1:
125 /* uninitialized! */
126 BLI_assert(0);
127 break;
128#endif
129 default:
130 /* nothing */
131 break;
132 }
133 dist_fac_invert[i + size] = val;
134 }
135
136 return dist_fac_invert;
137}
138
140{
141 memcpy(&data_, data, sizeof(NodeBlurData));
142}
143
145{
146 switch (dim) {
147 case eDimension::X:
148 return data_.sizex;
149 case eDimension::Y:
150 return data_.sizey;
151 }
152 return -1;
153}
154
156{
158 return;
159 }
160
162 if (size_input->get_flags().is_constant_operation) {
163 size_ = *static_cast<ConstantOperation *>(size_input)->get_constant_elem();
164 } /* Else use default. */
165 sizeavailable_ = true;
166}
167
168void BlurBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
169{
170 if (!extend_bounds_) {
171 NodeOperation::determine_canvas(preferred_area, r_area);
172 return;
173 }
174
175 /* Setting a modifier ensures all non main inputs have extended bounds as preferred
176 * canvas, avoiding unnecessary canvas conversions that would hide constant
177 * operations. */
179 /* Rounding to even prevents jiggling in backdrop while switching size values. */
180 canvas.xmax += round_to_even(2 * size_ * data_.sizex);
181 canvas.ymax += round_to_even(2 * size_ * data_.sizey);
182 });
183 NodeOperation::determine_canvas(preferred_area, r_area);
184}
185
187 const rcti &output_area,
188 rcti &r_input_area)
189{
190 switch (input_idx) {
191 case 0:
192 r_input_area = output_area;
193 break;
194 case 1:
195 r_input_area = use_variable_size_ ? output_area : COM_CONSTANT_INPUT_AREA_OF_INTEREST;
196 break;
197 }
198}
199
200} // namespace blender::compositor
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE int round_fl_to_int(float a)
MINLINE float round_to_even(float f)
@ CMP_NODE_BLUR_ASPECT_NONE
@ CMP_NODE_BLUR_ASPECT_X
@ CMP_NODE_BLUR_ASPECT_Y
@ PROP_SMOOTH
@ PROP_ROOT
@ PROP_SHARP
@ PROP_LIN
@ PROP_INVSQUARE
@ PROP_SPHERE
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static T sum(const btAlignedObjectArray< T > &items)
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
float * make_dist_fac_inverse(float rad, int size, int falloff)
NodeOperation contains calculation logic.
void add_output_socket(DataType datatype)
const NodeOperationFlags get_flags() const
NodeOperation * get_input_operation(int index)
void set_determined_canvas_modifier(std::function< void(rcti &canvas)> fn)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void determine_canvas(const rcti &preferred_area, rcti &r_area)
#define fabsf(x)
#define sqrtf(x)
DataType
possible data types for sockets
Definition COM_defines.h:21
float RE_filter_value(int type, float x)
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
constexpr rcti COM_CONSTANT_INPUT_AREA_OF_INTEREST
Definition COM_defines.h:90
int ymax
int xmax