Changeset View
Changeset View
Standalone View
Standalone View
source/blender/compositor/operations/COM_EllipseMaskOperation.cc
| Show All 14 Lines | |||||
| * | * | ||||
| * Copyright 2011, Blender Foundation. | * Copyright 2011, Blender Foundation. | ||||
| */ | */ | ||||
| #include "COM_EllipseMaskOperation.h" | #include "COM_EllipseMaskOperation.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "DNA_node_types.h" | #include "DNA_node_types.h" | ||||
| #include <functional> | |||||
| namespace blender::compositor { | namespace blender::compositor { | ||||
| EllipseMaskOperation::EllipseMaskOperation() | EllipseMaskOperation::EllipseMaskOperation() | ||||
| { | { | ||||
| this->addInputSocket(DataType::Value); | this->addInputSocket(DataType::Value); | ||||
| this->addInputSocket(DataType::Value); | this->addInputSocket(DataType::Value); | ||||
| this->addOutputSocket(DataType::Value); | this->addOutputSocket(DataType::Value); | ||||
| this->m_inputMask = nullptr; | this->m_inputMask = nullptr; | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | case CMP_NODE_MASKTYPE_NOT: | ||||
| } | } | ||||
| else { | else { | ||||
| output[0] = inputMask[0]; | output[0] = inputMask[0]; | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| void EllipseMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, | |||||
| const rcti &area, | |||||
| Span<MemoryBuffer *> 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 EllipseMaskOperation::apply_mask(MemoryBuffer *output, | |||||
| const rcti &area, | |||||
| Span<MemoryBuffer *> inputs, | |||||
| MaskFunc mask_func) | |||||
| { | |||||
| const MemoryBuffer *input_mask = inputs[0]; | |||||
| const MemoryBuffer *input_value = inputs[1]; | |||||
| 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; | |||||
| const float tx = half_w * half_w; | |||||
| const float ty = half_h * half_h; | |||||
| for (const int y : YRange(area)) { | |||||
| const float op_ry = y / op_h; | |||||
| const float dy = (op_ry - this->m_data->y) / m_aspectRatio; | |||||
| float *out = output->get_elem(area.xmin, y); | |||||
| const float *mask = input_mask->get_elem(area.xmin, y); | |||||
| const float *value = input_value->get_elem(area.xmin, y); | |||||
| for (const int x : XRange(area)) { | |||||
| const float op_rx = 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); | |||||
| float sx = rx - this->m_data->x; | |||||
| sx *= sx; | |||||
| float sy = ry - this->m_data->y; | |||||
| sy *= sy; | |||||
| const bool inside = ((sx / tx) + (sy / ty)) < 1.0f; | |||||
| out[0] = mask_func(inside, mask, value); | |||||
| mask += input_mask->elem_stride; | |||||
| value += input_value->elem_stride; | |||||
| out += output->elem_stride; | |||||
| } | |||||
| } | |||||
| } | |||||
| void EllipseMaskOperation::deinitExecution() | void EllipseMaskOperation::deinitExecution() | ||||
| { | { | ||||
| this->m_inputMask = nullptr; | this->m_inputMask = nullptr; | ||||
| this->m_inputValue = nullptr; | this->m_inputValue = nullptr; | ||||
| } | } | ||||
| } // namespace blender::compositor | } // namespace blender::compositor | ||||