13 flags_.can_be_constant =
true;
21 if (distance_ < 0.0f) {
22 scope_ = -distance_ + inset_;
25 if (inset_ * 2 > distance_) {
26 scope_ = std::max(inset_ * 2 - distance_, distance_);
38 const rcti &output_area,
43 r_input_area.
xmin = output_area.
xmin - scope_;
44 r_input_area.
xmax = output_area.
xmax + scope_;
45 r_input_area.
ymin = output_area.
ymin - scope_;
46 r_input_area.
ymax = output_area.
ymax + scope_;
64template<
template<
typename>
typename TCompare>
70 const TCompare compare;
74 for (
int yi = p.
ymin; yi < p.
ymax; yi++) {
75 const float dy = yi - p.
y;
76 const float dist_y = dy * dy;
77 const float *elem = row;
78 for (
int xi = p.
xmin; xi < p.
xmax; xi++) {
79 if (compare(*elem, p.
sw)) {
80 const float dx = xi - p.
x;
81 const float dist = dx * dx + dist_y;
82 min_dist = std::min(min_dist, dist);
97 const float rd = scope_ * scope_;
98 const float inset = inset_;
108 p.
xmin = std::max(p.
x - scope_, input_rect.
xmin);
109 p.
ymin = std::max(p.
y - scope_, input_rect.
ymin);
110 p.
xmax = std::min(p.
x + scope_, input_rect.
xmax);
111 p.
ymax = std::min(p.
y + scope_, input_rect.
ymax);
122 if (distance_ > 0.0f) {
123 const float delta = distance_ - pixel_value;
125 *it.out = delta >= inset ? 1.0f : delta / inset;
132 const float delta = -distance_ + pixel_value;
134 *it.out = delta < -inset ? 1.0f : (-delta) / inset;
148 flags_.can_be_constant =
true;
160 const rcti &output_area,
206template<
template<
typename>
typename TCompare>
211 const TCompare compare;
213 float value = start_value;
216 for (
int yi = p.
ymin; yi < p.
ymax; yi++) {
217 const float dy = yi - p.
y;
218 const float dist_y = dy * dy;
219 const float *elem = row;
220 for (
int xi = p.
xmin; xi < p.
xmax; xi++) {
221 const float dx = xi - p.
x;
222 const float dist = dx * dx + dist_y;
223 if (dist <= min_dist) {
224 value = compare(*elem, value) ? *elem : value;
268 const rcti &output_area,
279template<
typename TCompareSelector>
283 const int num_iterations,
284 const float compare_min_value)
286 TCompareSelector selector;
288 const int width =
output->get_width();
289 const int height =
output->get_height();
291 const int half_window = num_iterations;
292 const int window = half_window * 2 + 1;
294 const int xmin = std::max(0, area.
xmin - half_window);
295 const int ymin = std::max(0, area.
ymin - half_window);
296 const int xmax = std::min(width, area.
xmax + half_window);
297 const int ymax = std::min(height, area.
ymax + half_window);
299 const int bwidth = area.
xmax - area.
xmin;
300 const int bheight = area.
ymax - area.
ymin;
312 float *temp = (
float *)
MEM_mallocN(
sizeof(
float) * (2 * window - 1),
"dilate erode temp");
313 float *buf = (
float *)
MEM_mallocN(
sizeof(
float) * (std::max(bwidth, bheight) + 5 * half_window),
318 for (
int y = ymin;
y < ymax;
y++) {
319 for (
int x = 0;
x < bwidth + 5 * half_window;
x++) {
320 buf[
x] = compare_min_value;
322 for (
int x = xmin;
x < xmax;
x++) {
326 for (
int i = 0; i < (bwidth + 3 * half_window) / window; i++) {
327 int start = (i + 1) * window - 1;
329 temp[window - 1] = buf[start];
330 for (
int x = 1;
x < window;
x++) {
331 temp[window - 1 -
x] = selector(temp[window -
x], buf[start -
x]);
332 temp[window - 1 +
x] = selector(temp[window +
x - 2], buf[start +
x]);
335 start = half_window + (i - 1) * window + 1;
336 for (
int x = -std::min(0, start);
x < window - std::max(0, start + window - bwidth);
x++) {
337 result.get_value(start +
x + area.
xmin,
y, 0) = selector(temp[
x], temp[
x + window - 1]);
343 for (
int x = 0;
x < bwidth;
x++) {
344 for (
int y = 0;
y < bheight + 5 * half_window;
y++) {
345 buf[
y] = compare_min_value;
347 for (
int y = ymin;
y < ymax;
y++) {
351 for (
int i = 0; i < (bheight + 3 * half_window) / window; i++) {
352 int start = (i + 1) * window - 1;
354 temp[window - 1] = buf[start];
355 for (
int y = 1;
y < window;
y++) {
356 temp[window - 1 -
y] = selector(temp[window -
y], buf[start -
y]);
357 temp[window - 1 +
y] = selector(temp[window +
y - 2], buf[start +
y]);
360 start = half_window + (i - 1) * window + 1;
361 for (
int y = -std::min(0, start);
y < window - std::max(0, start + window - bheight);
y++) {
363 temp[
y + window - 1]);
377 return std::max(f1, f2);
396 return std::min(f1, f2);
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
#define UNUSED_VARS_NDEBUG(...)
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final
Get input operation area being read by this operation on rendering given output area.
virtual void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
DilateDistanceOperation()
void init_data() override
DilateErodeThresholdOperation()
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.
void init_data() override
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
virtual void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final
Get input operation area being read by this operation on rendering given output area.
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
a MemoryBuffer contains access to the data
const rcti & get_rect() const
get the rect of this MemoryBuffer
float & get_value(int x, int y, int channel)
void add_output_socket(DataType datatype)
NodeOperationFlags flags_
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
static void step_update_memory_buffer(MemoryBuffer *output, const MemoryBuffer *input, const rcti &area, const int num_iterations, const float compare_min_value)
static float get_min_distance(DilateErodeThresholdOperation::PixelData &p)
static float get_distance_value(DilateDistanceOperation::PixelData &p, const float start_value)
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
static blender::bke::bNodeSocketTemplate inputs[]
float distance(float a, float b)
PixelData(MemoryBuffer *input, const int distance, const int scope)
void update(BuffersIterator< float > &it)
float operator()(float f1, float f2) const
float operator()(float f1, float f2) const