[Bf-blender-cvs] [344aca3b1bf] master: Compositor: Full frame distort nodes

Manuel Castilla noreply at git.blender.org
Mon Aug 23 17:18:41 CEST 2021


Commit: 344aca3b1bf2718904455ea6cef1ffd8bedf51a6
Author: Manuel Castilla
Date:   Mon Aug 23 15:30:18 2021 +0200
Branches: master
https://developer.blender.org/rB344aca3b1bf2718904455ea6cef1ffd8bedf51a6

Compositor: Full frame distort nodes

Adds full frame implementation to "Displace", "Crop", "Flip",
"Plane Track Deform", "Corner Pin", "Movie Distortion",
"Lens Distortion" and "Map UV" nodes.

The other nodes in "Distort" sub-menu are implemented
separately in other commits.

No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12166

===================================================================

M	source/blender/compositor/operations/COM_CropOperation.cc
M	source/blender/compositor/operations/COM_CropOperation.h
M	source/blender/compositor/operations/COM_DisplaceOperation.cc
M	source/blender/compositor/operations/COM_DisplaceOperation.h
M	source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc
M	source/blender/compositor/operations/COM_DisplaceSimpleOperation.h
M	source/blender/compositor/operations/COM_FlipOperation.cc
M	source/blender/compositor/operations/COM_FlipOperation.h
M	source/blender/compositor/operations/COM_MapUVOperation.cc
M	source/blender/compositor/operations/COM_MapUVOperation.h
M	source/blender/compositor/operations/COM_MovieDistortionOperation.cc
M	source/blender/compositor/operations/COM_MovieDistortionOperation.h
M	source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
M	source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
M	source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
M	source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
M	source/blender/compositor/operations/COM_PlaneTrackOperation.cc
M	source/blender/compositor/operations/COM_PlaneTrackOperation.h
M	source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc
M	source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
M	source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
M	source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h

===================================================================

diff --git a/source/blender/compositor/operations/COM_CropOperation.cc b/source/blender/compositor/operations/COM_CropOperation.cc
index f12d93bc8d3..12833660fcb 100644
--- a/source/blender/compositor/operations/COM_CropOperation.cc
+++ b/source/blender/compositor/operations/COM_CropOperation.cc
@@ -95,6 +95,22 @@ void CropOperation::executePixelSampled(float output[4], float x, float y, Pixel
   }
 }
 
+void CropOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                 const rcti &area,
+                                                 Span<MemoryBuffer *> inputs)
+{
+  rcti crop_area;
+  BLI_rcti_init(&crop_area, m_xmin, m_xmax, m_ymin, m_ymax);
+  for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+    if (BLI_rcti_isect_pt(&crop_area, it.x, it.y)) {
+      copy_v4_v4(it.out, it.in(0));
+    }
+    else {
+      zero_v4(it.out);
+    }
+  }
+}
+
 CropImageOperation::CropImageOperation() : CropBaseOperation()
 {
   /* pass */
@@ -114,6 +130,18 @@ bool CropImageOperation::determineDependingAreaOfInterest(rcti *input,
   return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
 }
 
+void CropImageOperation::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.xmax = output_area.xmax + this->m_xmin;
+  r_input_area.xmin = output_area.xmin + this->m_xmin;
+  r_input_area.ymax = output_area.ymax + this->m_ymin;
+  r_input_area.ymin = output_area.ymin + this->m_ymin;
+}
+
 void CropImageOperation::determineResolution(unsigned int resolution[2],
                                              unsigned int preferredResolution[2])
 {
@@ -136,4 +164,21 @@ void CropImageOperation::executePixelSampled(float output[4],
   }
 }
 
+void CropImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                      const rcti &area,
+                                                      Span<MemoryBuffer *> inputs)
+{
+  rcti op_area;
+  BLI_rcti_init(&op_area, 0, getWidth(), 0, getHeight());
+  const MemoryBuffer *input = inputs[0];
+  for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+    if (BLI_rcti_isect_pt(&op_area, it.x, it.y)) {
+      input->read_elem_checked(it.x + this->m_xmin, it.y + this->m_ymin, it.out);
+    }
+    else {
+      zero_v4(it.out);
+    }
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h
index acdff79a77c..57caa4e5834 100644
--- a/source/blender/compositor/operations/COM_CropOperation.h
+++ b/source/blender/compositor/operations/COM_CropOperation.h
@@ -18,11 +18,11 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
-class CropBaseOperation : public NodeOperation {
+class CropBaseOperation : public MultiThreadedOperation {
  protected:
   SocketReader *m_inputOperation;
   NodeTwoXYs *m_settings;
@@ -53,6 +53,10 @@ class CropOperation : public CropBaseOperation {
  public:
   CropOperation();
   void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
 };
 
 class CropImageOperation : public CropBaseOperation {
@@ -65,6 +69,11 @@ class CropImageOperation : public CropBaseOperation {
   void determineResolution(unsigned int resolution[2],
                            unsigned int preferredResolution[2]) override;
   void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+  void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
 };
 
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc
index 9f3f5cfe489..a4c01fda7ca 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cc
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cc
@@ -32,20 +32,30 @@ DisplaceOperation::DisplaceOperation()
   this->flags.complex = true;
 
   this->m_inputColorProgram = nullptr;
-  this->m_inputVectorProgram = nullptr;
-  this->m_inputScaleXProgram = nullptr;
-  this->m_inputScaleYProgram = nullptr;
 }
 
 void DisplaceOperation::initExecution()
 {
   this->m_inputColorProgram = this->getInputSocketReader(0);
-  this->m_inputVectorProgram = this->getInputSocketReader(1);
-  this->m_inputScaleXProgram = this->getInputSocketReader(2);
-  this->m_inputScaleYProgram = this->getInputSocketReader(3);
+  NodeOperation *vector = this->getInputSocketReader(1);
+  NodeOperation *scale_x = this->getInputSocketReader(2);
+  NodeOperation *scale_y = this->getInputSocketReader(3);
+  if (execution_model_ == eExecutionModel::Tiled) {
+    vector_read_fn_ = [=](float x, float y, float *out) {
+      vector->readSampled(out, x, y, PixelSampler::Bilinear);
+    };
+    scale_x_read_fn_ = [=](float x, float y, float *out) {
+      scale_x->readSampled(out, x, y, PixelSampler::Nearest);
+    };
+    scale_y_read_fn_ = [=](float x, float y, float *out) {
+      scale_y->readSampled(out, x, y, PixelSampler::Nearest);
+    };
+  }
 
   this->m_width_x4 = this->getWidth() * 4;
   this->m_height_x4 = this->getHeight() * 4;
+  input_vector_width_ = vector->getWidth();
+  input_vector_height_ = vector->getHeight();
 }
 
 void DisplaceOperation::executePixelSampled(float output[4],
@@ -69,8 +79,8 @@ void DisplaceOperation::executePixelSampled(float output[4],
 bool DisplaceOperation::read_displacement(
     float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v)
 {
-  float width = m_inputVectorProgram->getWidth();
-  float height = m_inputVectorProgram->getHeight();
+  float width = input_vector_width_;
+  float height = input_vector_height_;
   if (x < 0.0f || x >= width || y < 0.0f || y >= height) {
     r_u = 0.0f;
     r_v = 0.0f;
@@ -78,7 +88,7 @@ bool DisplaceOperation::read_displacement(
   }
 
   float col[4];
-  m_inputVectorProgram->readSampled(col, x, y, PixelSampler::Bilinear);
+  vector_read_fn_(x, y, col);
   r_u = origin[0] - col[0] * xscale;
   r_v = origin[1] - col[1] * yscale;
   return true;
@@ -90,9 +100,9 @@ void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r
   float uv[2]; /* temporary variables for derivative estimation */
   int num;
 
-  m_inputScaleXProgram->readSampled(col, xy[0], xy[1], PixelSampler::Nearest);
+  scale_x_read_fn_(xy[0], xy[1], col);
   float xs = col[0];
-  m_inputScaleYProgram->readSampled(col, xy[0], xy[1], PixelSampler::Nearest);
+  scale_y_read_fn_(xy[0], xy[1], col);
   float ys = col[0];
   /* clamp x and y displacement to triple image resolution -
    * to prevent hangs from huge values mistakenly plugged in eg. z buffers */
@@ -146,9 +156,9 @@ void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r
 void DisplaceOperation::deinitExecution()
 {
   this->m_inputColorProgram = nullptr;
-  this->m_inputVectorProgram = nullptr;
-  this->m_inputScaleXProgram = nullptr;
-  this->m_inputScaleYProgram = nullptr;
+  vector_read_fn_ = nullptr;
+  scale_x_read_fn_ = nullptr;
+  scale_y_read_fn_ = nullptr;
 }
 
 bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input,
@@ -195,4 +205,61 @@ bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input,
   return false;
 }
 
+void DisplaceOperation::get_area_of_interest(const int input_idx,
+                                             const rcti &output_area,
+                                             rcti &r_input_area)
+{
+  switch (input_idx) {
+    case 0: {
+      r_input_area.xmin = 0;
+      r_input_area.ymin = 0;
+      r_input_area.xmax = getInputOperation(input_idx)->getWidth();
+      r_input_area.ymax = getInputOperation(input_idx)->getHeight();
+      break;
+    }
+    case 1: {
+      r_input_area = output_area;
+      expand_area_for_sampler(r_input_area, PixelSampler::Bilinear);
+      break;
+    }
+    default: {
+      r_input_area = output_area;
+      break;
+    }
+  }
+}
+
+void DisplaceOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
+                                                     const rcti &UNUSED(area),
+                                                     Span<MemoryBuffer *> inputs)
+{
+  MemoryBuffer *vector = inputs[1];
+  MemoryBuffer *scale_x = inputs[2];
+  MemoryBuffer *scale_y = inputs[3];
+  vector_read_fn_ = [=](float x, float y, float *out) { vector->read_elem_bilinear(x, y, out); };
+  scale_x_read_fn_ = [=](float x, float y, float *out) { scale_x->read_elem_checked(x, y, out); };
+  scale_y_read_fn_ = [=](float x, float y, float *out) { scale_y->read_elem_checked(x, y, out); };
+}
+
+void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                     const rcti &area,
+                                                     Span<MemoryBuffer *> inputs)
+{
+  const MemoryBuffer *input_color = inputs[0];
+  for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+    const float xy[2] = {(float)it.x, (float)it.y};
+    float uv[2];
+    float deriv[2][2];
+
+    pixelTransform(xy, uv, deriv);
+    if (is_zero_v2(deriv[0]) && is_zero_v2(deriv[1])) {
+      input_color->read_elem_bilinear(uv[0], uv[1], it.out);
+    }
+    else {
+      /* EWA filtering (without nearest it gets blurry with NO distortion). */
+      input_color->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list