[Bf-blender-cvs] [79ffaa48165] compositor-full-frame: Compositor: Full frame Plane Track Deform and Corner Pin nodes

Manuel Castilla noreply at git.blender.org
Wed Aug 4 23:03:37 CEST 2021


Commit: 79ffaa48165a2df23f01964de2eeeca0ea56bdb8
Author: Manuel Castilla
Date:   Tue Aug 3 21:01:40 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rB79ffaa48165a2df23f01964de2eeeca0ea56bdb8

Compositor: Full frame Plane Track Deform and Corner Pin nodes

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

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

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

diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
index 3577860b93d..fcbf42c8713 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
@@ -16,6 +16,7 @@
  */
 
 #include "COM_PlaneCornerPinOperation.h"
+#include "COM_ConstantOperation.h"
 #include "COM_ReadBufferOperation.h"
 
 #include "MEM_guardedalloc.h"
@@ -28,6 +29,11 @@
 
 namespace blender::compositor {
 
+constexpr int LOWER_LEFT_CORNER_INDEX = 0;
+constexpr int LOWER_RIGHT_CORNER_INDEX = 1;
+constexpr int UPPER_RIGHT_CORNER_INDEX = 2;
+constexpr int UPPER_LEFT_CORNER_INDEX = 3;
+
 static bool check_corners(float corners[4][2])
 {
   int i, next, prev;
@@ -58,6 +64,7 @@ static bool check_corners(float corners[4][2])
   return true;
 }
 
+/* TODO(manzanilla): to be removed with tiled implementation. */
 static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float corners[4][2])
 {
   for (int i = 0; i < 4; i++) {
@@ -87,6 +94,53 @@ static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float c
   }
 }
 
+static void set_default_corner(const int corner_idx, float corner[2])
+{
+  BLI_assert(corner_idx >= 0 && corner_idx < 4);
+  switch (corner_idx) {
+    case LOWER_LEFT_CORNER_INDEX:
+      corner[0] = 0.0f;
+      corner[1] = 0.0f;
+      break;
+    case LOWER_RIGHT_CORNER_INDEX:
+      corner[0] = 1.0f;
+      corner[1] = 0.0f;
+      break;
+    case UPPER_RIGHT_CORNER_INDEX:
+      corner[0] = 1.0f;
+      corner[1] = 1.0f;
+      break;
+    case UPPER_LEFT_CORNER_INDEX:
+      corner[0] = 0.0f;
+      corner[1] = 1.0f;
+      break;
+  }
+}
+
+static void read_input_corners(NodeOperation *op, const int first_input_idx, float r_corners[4][2])
+{
+  for (const int i : IndexRange(4)) {
+    NodeOperation *input = op->get_input_operation(i + first_input_idx);
+    if (input->get_flags().is_constant_operation) {
+      ConstantOperation *corner_input = static_cast<ConstantOperation *>(input);
+      copy_v2_v2(r_corners[i], corner_input->get_constant_elem());
+    }
+    else {
+      set_default_corner(i, r_corners[i]);
+    }
+  }
+
+  /* Convexity check: concave corners need to be prevented, otherwise
+   * #BKE_tracking_homography_between_two_quads will freeze. */
+  if (!check_corners(r_corners)) {
+    /* Revert to default corners. There could be a more elegant solution,
+     * this prevents freezing at least. */
+    for (const int i : IndexRange(4)) {
+      set_default_corner(i, r_corners[i]);
+    }
+  }
+}
+
 /* ******** PlaneCornerPinMaskOperation ******** */
 
 PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() : m_corners_ready(false)
@@ -103,6 +157,17 @@ PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() : m_corners_ready(fal
   flags.complex = true;
 }
 
+void PlaneCornerPinMaskOperation::init_data()
+{
+  if (execution_model_ == eExecutionModel::FullFrame) {
+    float corners[4][2];
+    read_input_corners(this, 0, corners);
+    calculateCorners(corners, true, 0);
+  }
+}
+
+/* TODO(manzanilla): to be removed with tiled implementation. Same for #deinitExecution and do the
+ * same on #PlaneCornerPinWarpImageOperation. */
 void PlaneCornerPinMaskOperation::initExecution()
 {
   PlaneDistortMaskOperation::initExecution();
@@ -147,6 +212,10 @@ void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect)
 void PlaneCornerPinMaskOperation::determineResolution(unsigned int resolution[2],
                                                       unsigned int preferredResolution[2])
 {
+  if (execution_model_ == eExecutionModel::FullFrame) {
+    /* Determine inputs resolution. */
+    PlaneDistortMaskOperation::determineResolution(resolution, preferredResolution);
+  }
   resolution[0] = preferredResolution[0];
   resolution[1] = preferredResolution[1];
 }
@@ -161,6 +230,15 @@ PlaneCornerPinWarpImageOperation::PlaneCornerPinWarpImageOperation() : m_corners
   addInputSocket(DataType::Vector);
 }
 
+void PlaneCornerPinWarpImageOperation::init_data()
+{
+  if (execution_model_ == eExecutionModel::FullFrame) {
+    float corners[4][2];
+    read_input_corners(this, 1, corners);
+    calculateCorners(corners, true, 0);
+  }
+}
+
 void PlaneCornerPinWarpImageOperation::initExecution()
 {
   PlaneDistortWarpImageOperation::initExecution();
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
index 91c0cd9e16b..7d857d270a0 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h
@@ -31,11 +31,13 @@ namespace blender::compositor {
 
 class PlaneCornerPinMaskOperation : public PlaneDistortMaskOperation {
  private:
+  /* TODO(manzanilla): to be removed with tiled implementation. */
   bool m_corners_ready;
 
  public:
   PlaneCornerPinMaskOperation();
 
+  void init_data() override;
   void initExecution() override;
   void deinitExecution() override;
 
@@ -52,6 +54,7 @@ class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation {
  public:
   PlaneCornerPinWarpImageOperation();
 
+  void init_data() override;
   void initExecution() override;
   void deinitExecution() override;
 
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
index 4edcc206f5b..91af4f0e5aa 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
@@ -85,8 +85,9 @@ void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2],
 {
   PlaneDistortBaseOperation::calculateCorners(corners, normalized, sample);
 
-  const int width = this->m_pixelReader->getWidth();
-  const int height = this->m_pixelReader->getHeight();
+  const NodeOperation *image = get_input_operation(0);
+  const int width = image->getWidth();
+  const int height = image->getHeight();
   float frame_corners[4][2] = {
       {0.0f, 0.0f}, {(float)width, 0.0f}, {(float)width, (float)height}, {0.0f, (float)height}};
   MotionSample *sample_data = &this->m_samples[sample];
@@ -127,6 +128,34 @@ void PlaneDistortWarpImageOperation::executePixelSampled(float output[4],
   }
 }
 
+void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                                  const rcti &area,
+                                                                  Span<MemoryBuffer *> inputs)
+{
+  const MemoryBuffer *input_img = inputs[0];
+  float uv[2];
+  float deriv[2][2];
+  BuffersIterator<float> it = output->iterate_with({}, area);
+  if (this->m_motion_blur_samples == 1) {
+    for (; !it.is_end(); ++it) {
+      warpCoord(it.x, it.y, this->m_samples[0].perspectiveMatrix, uv, deriv);
+      input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], it.out);
+    }
+  }
+  else {
+    for (; !it.is_end(); ++it) {
+      zero_v4(it.out);
+      for (const int sample : IndexRange(this->m_motion_blur_samples)) {
+        float color[4];
+        warpCoord(it.x, it.y, this->m_samples[sample].perspectiveMatrix, uv, deriv);
+        input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], color);
+        add_v4_v4(it.out, color);
+      }
+      mul_v4_fl(it.out, 1.0f / (float)this->m_motion_blur_samples);
+    }
+  }
+}
+
 bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(
     rcti *input, ReadBufferOperation *readOperation, rcti *output)
 {
@@ -157,6 +186,41 @@ bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(
   return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
 }
 
+void PlaneDistortWarpImageOperation::get_area_of_interest(const int input_idx,
+                                                          const rcti &output_area,
+                                                          rcti &r_input_area)
+{
+  if (input_idx != 0) {
+    r_input_area = output_area;
+    return;
+  }
+
+  float min[2], max[2];
+  INIT_MINMAX2(min, max);
+  for (int sample = 0; sample < this->m_motion_blur_samples; sample++) {
+    float UVs[4][2];
+    float deriv[2][2];
+    MotionSample *sample_data = &this->m_samples[sample];
+    /* TODO(sergey): figure out proper way to do this. */
+    warpCoord(
+        output_area.xmin - 2, output_area.ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv);
+    warpCoord(
+        output_area.xmax + 2, output_area.ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv);
+    warpCoord(
+        output_area.xmax + 2, output_area.ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv);
+    warpCoord(
+        output_area.xmin - 2, output_area.ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv);
+    for (int i = 0; i < 4; i++) {
+      minmax_v2v2_v2(min, max, UVs[i]);
+    }
+  }
+
+  r_input_area.xmin = min[0] - 1;
+  r_input_area.ymin = min[1] - 1;
+  r_input_area.xmax = max[0] + 1;
+  r_input_area.ymax = max[1] + 1;
+}
+
 /* ******** PlaneDistort Mask ******** */
 
 PlaneDistortMaskOperation::PlaneDistortMaskOperation() : PlaneDistortBaseOperation()
@@ -219,4 +283,41 @@ void PlaneDistortMaskOperation::executePixelSampled(float output[4],
   }
 }
 
+void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                             const rcti &area,
+                                                             Span<MemoryBuffer *> UNUSED(inputs))
+{
+  for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+    int inside_count = 0;
+    for (const int motion_sample : IndexRange(this->m_motion_blur_samples)) {
+      MotionSample &sample = this->m_samples[motion_sample];
+      inside_count += get_jitter_samples_inside_count(it.x, it.y, sample);
+    }
+    *it.out = (float)inside_count / (this->m_osa * this->m_motion_blur_samples);
+  }
+}
+
+int PlaneDistortMaskOperation::get_jitter_sample

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list