[Bf-blender-cvs] [4745dfadde4] compositor-full-frame: Compositor: Full frame Transform node

Manuel Castilla noreply at git.blender.org
Wed Jul 28 23:29:59 CEST 2021


Commit: 4745dfadde418dba997e1e33cfff75c7dd896006
Author: Manuel Castilla
Date:   Wed Jul 28 23:24:44 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rB4745dfadde418dba997e1e33cfff75c7dd896006

Compositor: Full frame Transform node

In order to avoid sampling twice when concatenating
scale and rotate operations, a transform operation
is implemented for full frame with all the functionality.
The node has no functional changes.

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

M	source/blender/compositor/CMakeLists.txt
M	source/blender/compositor/nodes/COM_TransformNode.cc
M	source/blender/compositor/operations/COM_RotateOperation.cc
M	source/blender/compositor/operations/COM_RotateOperation.h
M	source/blender/compositor/operations/COM_ScaleOperation.cc
M	source/blender/compositor/operations/COM_ScaleOperation.h
A	source/blender/compositor/operations/COM_TransformOperation.cc
A	source/blender/compositor/operations/COM_TransformOperation.h

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

diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 830792a2a48..e397fcd2772 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -515,6 +515,8 @@ set(SRC
   operations/COM_ScaleOperation.h
   operations/COM_ScreenLensDistortionOperation.cc
   operations/COM_ScreenLensDistortionOperation.h
+  operations/COM_TransformOperation.cc
+  operations/COM_TransformOperation.h
   operations/COM_TranslateOperation.cc
   operations/COM_TranslateOperation.h
   operations/COM_WrapOperation.cc
diff --git a/source/blender/compositor/nodes/COM_TransformNode.cc b/source/blender/compositor/nodes/COM_TransformNode.cc
index e1deaf616a4..d2fb7b54633 100644
--- a/source/blender/compositor/nodes/COM_TransformNode.cc
+++ b/source/blender/compositor/nodes/COM_TransformNode.cc
@@ -22,6 +22,7 @@
 #include "COM_ScaleOperation.h"
 #include "COM_SetSamplerOperation.h"
 #include "COM_SetValueOperation.h"
+#include "COM_TransformOperation.h"
 #include "COM_TranslateOperation.h"
 
 namespace blender::compositor {
@@ -32,7 +33,7 @@ TransformNode::TransformNode(bNode *editorNode) : Node(editorNode)
 }
 
 void TransformNode::convertToOperations(NodeConverter &converter,
-                                        const CompositorContext & /*context*/) const
+                                        const CompositorContext &context) const
 {
   NodeInput *imageInput = this->getInputSocket(0);
   NodeInput *xInput = this->getInputSocket(1);
@@ -40,33 +41,51 @@ void TransformNode::convertToOperations(NodeConverter &converter,
   NodeInput *angleInput = this->getInputSocket(3);
   NodeInput *scaleInput = this->getInputSocket(4);
 
-  ScaleRelativeOperation *scaleOperation = new ScaleRelativeOperation();
-  converter.addOperation(scaleOperation);
+  switch (context.get_execution_model()) {
+    case eExecutionModel::Tiled: {
+      ScaleRelativeOperation *scaleOperation = new ScaleRelativeOperation();
+      converter.addOperation(scaleOperation);
 
-  RotateOperation *rotateOperation = new RotateOperation();
-  rotateOperation->setDoDegree2RadConversion(false);
-  converter.addOperation(rotateOperation);
+      RotateOperation *rotateOperation = new RotateOperation();
+      rotateOperation->setDoDegree2RadConversion(false);
+      converter.addOperation(rotateOperation);
 
-  TranslateOperation *translateOperation = new TranslateOperation();
-  converter.addOperation(translateOperation);
+      TranslateOperation *translateOperation = new TranslateOperation();
+      converter.addOperation(translateOperation);
 
-  SetSamplerOperation *sampler = new SetSamplerOperation();
-  sampler->setSampler((PixelSampler)this->getbNode()->custom1);
-  converter.addOperation(sampler);
+      SetSamplerOperation *sampler = new SetSamplerOperation();
+      sampler->setSampler((PixelSampler)this->getbNode()->custom1);
+      converter.addOperation(sampler);
 
-  converter.mapInputSocket(imageInput, sampler->getInputSocket(0));
-  converter.addLink(sampler->getOutputSocket(), scaleOperation->getInputSocket(0));
-  converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(1));
-  converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(2));  // xscale = yscale
+      converter.mapInputSocket(imageInput, sampler->getInputSocket(0));
+      converter.addLink(sampler->getOutputSocket(), scaleOperation->getInputSocket(0));
+      converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(1));
+      converter.mapInputSocket(scaleInput, scaleOperation->getInputSocket(2));  // xscale = yscale
 
-  converter.addLink(scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
-  converter.mapInputSocket(angleInput, rotateOperation->getInputSocket(1));
+      converter.addLink(scaleOperation->getOutputSocket(), rotateOperation->getInputSocket(0));
+      converter.mapInputSocket(angleInput, rotateOperation->getInputSocket(1));
 
-  converter.addLink(rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
-  converter.mapInputSocket(xInput, translateOperation->getInputSocket(1));
-  converter.mapInputSocket(yInput, translateOperation->getInputSocket(2));
+      converter.addLink(rotateOperation->getOutputSocket(), translateOperation->getInputSocket(0));
+      converter.mapInputSocket(xInput, translateOperation->getInputSocket(1));
+      converter.mapInputSocket(yInput, translateOperation->getInputSocket(2));
 
-  converter.mapOutputSocket(getOutputSocket(), translateOperation->getOutputSocket());
+      converter.mapOutputSocket(getOutputSocket(), translateOperation->getOutputSocket());
+      break;
+    }
+    case eExecutionModel::FullFrame: {
+      TransformOperation *op = new TransformOperation();
+      op->set_sampler((PixelSampler)this->getbNode()->custom1);
+      converter.addOperation(op);
+
+      converter.mapInputSocket(imageInput, op->getInputSocket(0));
+      converter.mapInputSocket(xInput, op->getInputSocket(1));
+      converter.mapInputSocket(yInput, op->getInputSocket(2));
+      converter.mapInputSocket(angleInput, op->getInputSocket(3));
+      converter.mapInputSocket(scaleInput, op->getInputSocket(4));
+      converter.mapOutputSocket(getOutputSocket(), op->getOutputSocket());
+      break;
+    }
+  }
 }
 
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index f34bbeb2173..dbfa88ec193 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cc
+++ b/source/blender/compositor/operations/COM_RotateOperation.cc
@@ -36,6 +36,37 @@ RotateOperation::RotateOperation()
   sampler_ = PixelSampler::Nearest;
 }
 
+void RotateOperation::get_area_rotation_bounds(const rcti &area,
+                                               const float center_x,
+                                               const float center_y,
+                                               const float sine,
+                                               const float cosine,
+                                               rcti &r_bounds)
+{
+  const float dxmin = area.xmin - center_x;
+  const float dymin = area.ymin - center_y;
+  const float dxmax = area.xmax - center_x;
+  const float dymax = area.ymax - center_y;
+
+  const float x1 = center_x + (cosine * dxmin + sine * dymin);
+  const float x2 = center_x + (cosine * dxmax + sine * dymin);
+  const float x3 = center_x + (cosine * dxmin + sine * dymax);
+  const float x4 = center_x + (cosine * dxmax + sine * dymax);
+  const float y1 = center_y + (-sine * dxmin + cosine * dymin);
+  const float y2 = center_y + (-sine * dxmax + cosine * dymin);
+  const float y3 = center_y + (-sine * dxmin + cosine * dymax);
+  const float y4 = center_y + (-sine * dxmax + cosine * dymax);
+  const float minx = MIN2(x1, MIN2(x2, MIN2(x3, x4)));
+  const float maxx = MAX2(x1, MAX2(x2, MAX2(x3, x4)));
+  const float miny = MIN2(y1, MIN2(y2, MIN2(y3, y4)));
+  const float maxy = MAX2(y1, MAX2(y2, MAX2(y3, y4)));
+
+  r_bounds.xmin = floor(minx);
+  r_bounds.xmax = ceil(maxx);
+  r_bounds.ymin = floor(miny);
+  r_bounds.ymax = ceil(maxy);
+}
+
 void RotateOperation::init_data()
 {
   this->m_centerX = (getWidth() - 1) / 2.0;
@@ -138,28 +169,7 @@ void RotateOperation::get_area_of_interest(const int input_idx,
   }
 
   ensureDegree();
-  const float dxmin = output_area.xmin - this->m_centerX;
-  const float dymin = output_area.ymin - this->m_centerY;
-  const float dxmax = output_area.xmax - this->m_centerX;
-  const float dymax = output_area.ymax - this->m_centerY;
-
-  const float x1 = this->m_centerX + (this->m_cosine * dxmin + this->m_sine * dymin);
-  const float x2 = this->m_centerX + (this->m_cosine * dxmax + this->m_sine * dymin);
-  const float x3 = this->m_centerX + (this->m_cosine * dxmin + this->m_sine * dymax);
-  const float x4 = this->m_centerX + (this->m_cosine * dxmax + this->m_sine * dymax);
-  const float y1 = this->m_centerY + (-this->m_sine * dxmin + this->m_cosine * dymin);
-  const float y2 = this->m_centerY + (-this->m_sine * dxmax + this->m_cosine * dymin);
-  const float y3 = this->m_centerY + (-this->m_sine * dxmin + this->m_cosine * dymax);
-  const float y4 = this->m_centerY + (-this->m_sine * dxmax + this->m_cosine * dymax);
-  const float minx = MIN2(x1, MIN2(x2, MIN2(x3, x4)));
-  const float maxx = MAX2(x1, MAX2(x2, MAX2(x3, x4)));
-  const float miny = MIN2(y1, MIN2(y2, MIN2(y3, y4)));
-  const float maxy = MAX2(y1, MAX2(y2, MAX2(y3, y4)));
-
-  r_input_area.xmin = floor(minx);
-  r_input_area.xmax = ceil(maxx);
-  r_input_area.ymin = floor(miny);
-  r_input_area.ymax = ceil(maxy);
+  get_area_rotation_bounds(output_area, m_centerX, m_centerY, m_sine, m_cosine, r_input_area);
   expand_area_for_sampler(r_input_area, sampler_);
 }
 
@@ -170,11 +180,10 @@ void RotateOperation::update_memory_buffer_partial(MemoryBuffer *output,
   ensureDegree();
   const MemoryBuffer *input_img = inputs[0];
   for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
-    const float dy = it.y - this->m_centerY;
-    const float dx = it.x - this->m_centerX;
-    const float nx = this->m_centerX + (this->m_cosine * dx + this->m_sine * dy);
-    const float ny = this->m_centerY + (-this->m_sine * dx + this->m_cosine * dy);
-    input_img->read_elem_sampled(nx, ny, sampler_, it.out);
+    float x = it.x;
+    float y = it.y;
+    rotate_coords(x, y, m_centerX, m_centerY, m_sine, m_cosine);
+    input_img->read_elem_sampled(x, y, sampler_, it.out);
   }
 }
 
diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h
index 29d33379264..56224811238 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.h
+++ b/source/blender/compositor/operations/COM_RotateOperation.h
@@ -36,6 +36,22 @@ class RotateOperation : public MultiThreadedOperation {
 
  public:
   RotateOperation();
+
+  static void rotate_coords(
+      float &x, float &y, float center_x, float center_y, float sine, float cosine)
+  {
+    const float dx = x - center_x;
+    const float dy = y - center_y;
+    x = c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list