Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/operations/COM_KeyingClipOperation.cc')
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cc85
1 files changed, 85 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
index 4029be4e077..817c920ed91 100644
--- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
@@ -130,4 +130,89 @@ bool KeyingClipOperation::determineDependingAreaOfInterest(rcti *input,
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
+void KeyingClipOperation::get_area_of_interest(const int input_idx,
+ const rcti &output_area,
+ rcti &r_input_area)
+{
+ BLI_assert(input_idx == 0);
+ UNUSED_VARS_NDEBUG(input_idx);
+ r_input_area.xmin = output_area.xmin - m_kernelRadius;
+ r_input_area.xmax = output_area.xmax + m_kernelRadius;
+ r_input_area.ymin = output_area.ymin - m_kernelRadius;
+ r_input_area.ymax = output_area.ymax + m_kernelRadius;
+}
+
+void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ const MemoryBuffer *input = inputs[0];
+ BuffersIterator<float> it = output->iterate_with(inputs, area);
+
+ const int delta = m_kernelRadius;
+ const float tolerance = m_kernelTolerance;
+ const int width = this->getWidth();
+ const int height = this->getHeight();
+ const int row_stride = input->row_stride;
+ const int elem_stride = input->elem_stride;
+ for (; !it.is_end(); ++it) {
+ const int x = it.x;
+ const int y = it.y;
+
+ const int start_x = MAX2(0, x - delta + 1);
+ const int start_y = MAX2(0, y - delta + 1);
+ const int end_x = MIN2(x + delta, width);
+ const int end_y = MIN2(y + delta, height);
+ const int x_len = end_x - start_x;
+ const int y_len = end_y - start_y;
+
+ const int total_count = x_len * y_len - 1;
+ const int threshold_count = ceil((float)total_count * 0.9f);
+ bool ok = false;
+ if (delta == 0) {
+ ok = true;
+ }
+
+ const float *main_elem = it.in(0);
+ const float value = *main_elem;
+ const float *row = input->get_elem(start_x, start_y);
+ const float *end_row = row + y_len * row_stride;
+ int count = 0;
+ for (; ok == false && row < end_row; row += row_stride) {
+ const float *end_elem = row + x_len * elem_stride;
+ for (const float *elem = row; ok == false && elem < end_elem; elem += elem_stride) {
+ if (UNLIKELY(elem == main_elem)) {
+ continue;
+ }
+
+ const float current_value = *elem;
+ if (fabsf(current_value - value) < tolerance) {
+ count++;
+ if (count >= threshold_count) {
+ ok = true;
+ }
+ }
+ }
+ }
+
+ if (m_isEdgeMatte) {
+ *it.out = ok ? 0.0f : 1.0f;
+ }
+ else {
+ if (!ok) {
+ *it.out = value;
+ }
+ else if (value < m_clipBlack) {
+ *it.out = 0.0f;
+ }
+ else if (value >= m_clipWhite) {
+ *it.out = 1.0f;
+ }
+ else {
+ *it.out = (value - m_clipBlack) / (m_clipWhite - m_clipBlack);
+ }
+ }
+ }
+}
+
} // namespace blender::compositor