Blender  V3.3
COM_BlurBaseOperation.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
6 
7 #include "RE_pipeline.h"
8 
9 namespace blender::compositor {
10 
12 {
13  /* data_type is almost always DataType::Color except for alpha-blur */
14  this->add_input_socket(data_type);
16  this->add_output_socket(data_type);
17  flags_.complex = true;
18  input_program_ = nullptr;
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  update_size();
30  }
31 
32  data_.image_in_width = this->get_width();
34  if (data_.relative) {
35  int sizex, sizey;
36  switch (data_.aspect) {
38  sizex = sizey = data_.image_in_width;
39  break;
41  sizex = sizey = data_.image_in_height;
42  break;
43  default:
45  sizex = data_.image_in_width;
46  sizey = data_.image_in_height;
47  break;
48  }
49  data_.sizex = round_fl_to_int(data_.percentx * 0.01f * sizex);
50  data_.sizey = round_fl_to_int(data_.percenty * 0.01f * sizey);
51  }
52 }
53 
55 {
58 
60 }
61 
62 float *BlurBaseOperation::make_gausstab(float rad, int size)
63 {
64  float *gausstab, sum, val;
65  int i, n;
66 
67  n = 2 * size + 1;
68 
69  gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__);
70 
71  sum = 0.0f;
72  float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
73  for (i = -size; i <= size; i++) {
74  val = RE_filter_value(data_.filtertype, (float)i * fac);
75  sum += val;
76  gausstab[i + size] = val;
77  }
78 
79  sum = 1.0f / sum;
80  for (i = 0; i < n; i++) {
81  gausstab[i] *= sum;
82  }
83 
84  return gausstab;
85 }
86 
87 #ifdef BLI_HAVE_SSE2
88 __m128 *BlurBaseOperation::convert_gausstab_sse(const float *gausstab, int size)
89 {
90  int n = 2 * size + 1;
91  __m128 *gausstab_sse = (__m128 *)MEM_mallocN_aligned(sizeof(__m128) * n, 16, "gausstab sse");
92  for (int i = 0; i < n; i++) {
93  gausstab_sse[i] = _mm_set1_ps(gausstab[i]);
94  }
95  return gausstab_sse;
96 }
97 #endif
98 
99 float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff)
100 {
101  float *dist_fac_invert, val;
102  int i, n;
103 
104  n = 2 * size + 1;
105 
106  dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__);
107 
108  float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
109  for (i = -size; i <= size; i++) {
110  val = 1.0f - fabsf((float)i * fac);
111 
112  /* keep in sync with rna_enum_proportional_falloff_curve_only_items */
113  switch (falloff) {
114  case PROP_SMOOTH:
115  /* ease - gives less hard lines for dilate/erode feather */
116  val = (3.0f * val * val - 2.0f * val * val * val);
117  break;
118  case PROP_SPHERE:
119  val = sqrtf(2.0f * val - val * val);
120  break;
121  case PROP_ROOT:
122  val = sqrtf(val);
123  break;
124  case PROP_SHARP:
125  val = val * val;
126  break;
127  case PROP_INVSQUARE:
128  val = val * (2.0f - val);
129  break;
130  case PROP_LIN:
131  /* nothing to do */
132  break;
133 #ifndef NDEBUG
134  case -1:
135  /* uninitialized! */
136  BLI_assert(0);
137  break;
138 #endif
139  default:
140  /* nothing */
141  break;
142  }
143  dist_fac_invert[i + size] = val;
144  }
145 
146  return dist_fac_invert;
147 }
148 
150 {
151  input_program_ = nullptr;
152  input_size_ = nullptr;
153 }
154 
156 {
157  memcpy(&data_, data, sizeof(NodeBlurData));
158 }
159 
161 {
162  switch (dim) {
163  case eDimension::X:
164  return data_.sizex;
165  case eDimension::Y:
166  return data_.sizey;
167  }
168  return -1;
169 }
170 
172 {
174  return;
175  }
176 
177  switch (execution_model_) {
178  case eExecutionModel::Tiled: {
179  float result[4];
181  size_ = result[0];
182  break;
183  }
186  if (size_input->get_flags().is_constant_operation) {
187  size_ = *static_cast<ConstantOperation *>(size_input)->get_constant_elem();
188  } /* Else use default. */
189  break;
190  }
191  }
192  sizeavailable_ = true;
193 }
194 
195 void BlurBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
196 {
197  if (!extend_bounds_) {
198  NodeOperation::determine_canvas(preferred_area, r_area);
199  return;
200  }
201 
202  switch (execution_model_) {
203  case eExecutionModel::Tiled: {
204  NodeOperation::determine_canvas(preferred_area, r_area);
205  r_area.xmax += 2 * size_ * data_.sizex;
206  r_area.ymax += 2 * size_ * data_.sizey;
207  break;
208  }
210  /* Setting a modifier ensures all non main inputs have extended bounds as preferred
211  * canvas, avoiding unnecessary canvas conversions that would hide constant
212  * operations. */
213  set_determined_canvas_modifier([=](rcti &canvas) {
214  /* Rounding to even prevents jiggling in backdrop while switching size values. */
215  canvas.xmax += round_to_even(2 * size_ * data_.sizex);
216  canvas.ymax += round_to_even(2 * size_ * data_.sizey);
217  });
218  NodeOperation::determine_canvas(preferred_area, r_area);
219  break;
220  }
221  }
222 }
223 
225  const rcti &output_area,
226  rcti &r_input_area)
227 {
228  switch (input_idx) {
229  case 0:
230  r_input_area = output_area;
231  break;
232  case 1:
233  r_input_area = use_variable_size_ ? output_area : COM_CONSTANT_INPUT_AREA_OF_INTEREST;
234  break;
235  }
236 }
237 
238 } // namespace blender::compositor
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE int round_fl_to_int(float a)
MINLINE float round_to_even(float f)
#define CMP_NODE_BLUR_ASPECT_X
#define CMP_NODE_BLUR_ASPECT_Y
#define CMP_NODE_BLUR_ASPECT_NONE
#define PROP_LIN
#define PROP_SPHERE
#define PROP_SMOOTH
#define PROP_ROOT
#define PROP_INVSQUARE
#define PROP_SHARP
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static T sum(const btAlignedObjectArray< T > &items)
void set_data(const NodeBlurData *data)
float * make_gausstab(float rad, int size)
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
SocketReader * get_input_socket_reader(unsigned int index)
NodeOperation * get_input_operation(int index)
void read_sampled(float result[4], float x, float y, PixelSampler sampler)
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)
DataType
possible data types for sockets
Definition: COM_defines.h:30
float RE_filter_value(int type, float x)
Definition: initrender.c:108
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:35
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
constexpr rcti COM_CONSTANT_INPUT_AREA_OF_INTEREST
Definition: COM_defines.h:113
int ymax
Definition: DNA_vec_types.h:64
int xmax
Definition: DNA_vec_types.h:63