From a4a72bffd33a6611de561292ff5a2e004a74867d Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Mon, 26 Jul 2021 19:36:22 +0200 Subject: Compositor: Full frame Box Mask node Adds full frame implementation to this node operation. No functional changes. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D11627 --- .../compositor/operations/COM_BoxMaskOperation.cc | 58 ++++++++++++++++++++++ .../compositor/operations/COM_BoxMaskOperation.h | 16 +++++- 2 files changed, 72 insertions(+), 2 deletions(-) (limited to 'source/blender/compositor') diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc index 9938d4a85ed..15bb19660dc 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc @@ -105,6 +105,64 @@ void BoxMaskOperation::executePixelSampled(float output[4], float x, float y, Pi } } +void BoxMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) +{ + MaskFunc mask_func; + switch (m_maskType) { + case CMP_NODE_MASKTYPE_ADD: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? MAX2(mask[0], value[0]) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_SUBTRACT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? CLAMPIS(mask[0] - value[0], 0, 1) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_MULTIPLY: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? mask[0] * value[0] : 0; + }; + break; + case CMP_NODE_MASKTYPE_NOT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + if (is_inside) { + return mask[0] > 0.0f ? 0.0f : value[0]; + } + return mask[0]; + }; + break; + } + apply_mask(output, area, inputs, mask_func); +} + +void BoxMaskOperation::apply_mask(MemoryBuffer *output, + const rcti &area, + Span inputs, + MaskFunc mask_func) +{ + const float op_w = this->getWidth(); + const float op_h = this->getHeight(); + const float half_w = this->m_data->width / 2.0f; + const float half_h = this->m_data->height / 2.0f; + for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { + const float op_ry = it.y / op_h; + const float dy = (op_ry - this->m_data->y) / m_aspectRatio; + const float op_rx = it.x / op_w; + const float dx = op_rx - this->m_data->x; + const float rx = this->m_data->x + (m_cosine * dx + m_sine * dy); + const float ry = this->m_data->y + (-m_sine * dx + m_cosine * dy); + + const bool inside = (rx > this->m_data->x - half_w && rx < this->m_data->x + half_w && + ry > this->m_data->y - half_h && ry < this->m_data->y + half_h); + const float *mask = it.in(0); + const float *value = it.in(1); + *it.out = mask_func(inside, mask, value); + } +} + void BoxMaskOperation::deinitExecution() { this->m_inputMask = nullptr; diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h index fdec7bdd8ca..4c48dde844a 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -18,12 +18,14 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" namespace blender::compositor { -class BoxMaskOperation : public NodeOperation { +class BoxMaskOperation : public MultiThreadedOperation { private: + using MaskFunc = std::function; + /** * Cached reference to the inputProgram */ @@ -64,6 +66,16 @@ class BoxMaskOperation : public NodeOperation { { this->m_maskType = maskType; } + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; + + private: + void apply_mask(MemoryBuffer *output, + const rcti &area, + Span inputs, + MaskFunc mask_func); }; } // namespace blender::compositor -- cgit v1.2.3