[Bf-blender-cvs] [499fbfa0a68] compositor-full-frame: Compositor: Full frame Rotate node

Manuel Castilla noreply at git.blender.org
Tue Jul 27 23:26:03 CEST 2021


Commit: 499fbfa0a682977be25ddc96ebbf48c9651bd500
Author: Manuel Castilla
Date:   Tue Jul 27 16:45:53 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rB499fbfa0a682977be25ddc96ebbf48c9651bd500

Compositor: Full frame Rotate node

Adds full frame implementation to this node operation.
No functional changes.

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

M	source/blender/compositor/nodes/COM_RotateNode.cc
M	source/blender/compositor/operations/COM_RotateOperation.cc
M	source/blender/compositor/operations/COM_RotateOperation.h

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

diff --git a/source/blender/compositor/nodes/COM_RotateNode.cc b/source/blender/compositor/nodes/COM_RotateNode.cc
index af5baa733dc..c2fd8ed5594 100644
--- a/source/blender/compositor/nodes/COM_RotateNode.cc
+++ b/source/blender/compositor/nodes/COM_RotateNode.cc
@@ -30,20 +30,31 @@ RotateNode::RotateNode(bNode *editorNode) : Node(editorNode)
 }
 
 void RotateNode::convertToOperations(NodeConverter &converter,
-                                     const CompositorContext & /*context*/) const
+                                     const CompositorContext &context) const
 {
   NodeInput *inputSocket = this->getInputSocket(0);
   NodeInput *inputDegreeSocket = this->getInputSocket(1);
   NodeOutput *outputSocket = this->getOutputSocket(0);
   RotateOperation *operation = new RotateOperation();
-  SetSamplerOperation *sampler = new SetSamplerOperation();
-  sampler->setSampler((PixelSampler)this->getbNode()->custom1);
-
-  converter.addOperation(sampler);
   converter.addOperation(operation);
 
-  converter.addLink(sampler->getOutputSocket(), operation->getInputSocket(0));
-  converter.mapInputSocket(inputSocket, sampler->getInputSocket(0));
+  PixelSampler sampler = (PixelSampler)this->getbNode()->custom1;
+  switch (context.get_execution_model()) {
+    case eExecutionModel::Tiled: {
+      SetSamplerOperation *sampler_op = new SetSamplerOperation();
+      sampler_op->setSampler(sampler);
+      converter.addOperation(sampler_op);
+      converter.addLink(sampler_op->getOutputSocket(), operation->getInputSocket(0));
+      converter.mapInputSocket(inputSocket, sampler_op->getInputSocket(0));
+      break;
+    }
+    case eExecutionModel::FullFrame: {
+      operation->set_sampler(sampler);
+      converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
+      break;
+    }
+  }
+
   converter.mapInputSocket(inputDegreeSocket, operation->getInputSocket(1));
   converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
 }
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index 4fb3d324992..f34bbeb2173 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cc
+++ b/source/blender/compositor/operations/COM_RotateOperation.cc
@@ -17,6 +17,8 @@
  */
 
 #include "COM_RotateOperation.h"
+#include "COM_ConstantOperation.h"
+
 #include "BLI_math.h"
 
 namespace blender::compositor {
@@ -31,13 +33,19 @@ RotateOperation::RotateOperation()
   this->m_degreeSocket = nullptr;
   this->m_doDegree2RadConversion = false;
   this->m_isDegreeSet = false;
+  sampler_ = PixelSampler::Nearest;
 }
+
+void RotateOperation::init_data()
+{
+  this->m_centerX = (getWidth() - 1) / 2.0;
+  this->m_centerY = (getHeight() - 1) / 2.0;
+}
+
 void RotateOperation::initExecution()
 {
   this->m_imageSocket = this->getInputSocketReader(0);
   this->m_degreeSocket = this->getInputSocketReader(1);
-  this->m_centerX = (getWidth() - 1) / 2.0;
-  this->m_centerY = (getHeight() - 1) / 2.0;
 }
 
 void RotateOperation::deinitExecution()
@@ -50,7 +58,19 @@ inline void RotateOperation::ensureDegree()
 {
   if (!this->m_isDegreeSet) {
     float degree[4];
-    this->m_degreeSocket->readSampled(degree, 0, 0, PixelSampler::Nearest);
+    switch (execution_model_) {
+      case eExecutionModel::Tiled:
+        this->m_degreeSocket->readSampled(degree, 0, 0, PixelSampler::Nearest);
+        break;
+      case eExecutionModel::FullFrame:
+        NodeOperation *degree_op = getInputOperation(1);
+        const bool is_constant_degree = degree_op->get_flags().is_constant_operation;
+        degree[0] = is_constant_degree ?
+                        static_cast<ConstantOperation *>(degree_op)->get_constant_elem()[0] :
+                        0.0f;
+        break;
+    }
+
     double rad;
     if (this->m_doDegree2RadConversion) {
       rad = DEG2RAD((double)degree[0]);
@@ -108,4 +128,54 @@ bool RotateOperation::determineDependingAreaOfInterest(rcti *input,
   return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
 }
 
+void RotateOperation::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;
+  }
+
+  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);
+  expand_area_for_sampler(r_input_area, sampler_);
+}
+
+void RotateOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                   const rcti &area,
+                                                   Span<MemoryBuffer *> inputs)
+{
+  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);
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h
index d76507f9816..29d33379264 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.h
+++ b/source/blender/compositor/operations/COM_RotateOperation.h
@@ -18,11 +18,11 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
-class RotateOperation : public NodeOperation {
+class RotateOperation : public MultiThreadedOperation {
  private:
   SocketReader *m_imageSocket;
   SocketReader *m_degreeSocket;
@@ -32,6 +32,7 @@ class RotateOperation : public NodeOperation {
   float m_sine;
   bool m_doDegree2RadConversion;
   bool m_isDegreeSet;
+  PixelSampler sampler_;
 
  public:
   RotateOperation();
@@ -39,14 +40,24 @@ class RotateOperation : public NodeOperation {
                                         ReadBufferOperation *readOperation,
                                         rcti *output) override;
   void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+  void init_data() override;
   void initExecution() override;
   void deinitExecution() override;
   void setDoDegree2RadConversion(bool abool)
   {
     this->m_doDegree2RadConversion = abool;
   }
+  void set_sampler(PixelSampler sampler)
+  {
+    sampler_ = sampler;
+  }
 
   void ensureDegree();
+
+  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



More information about the Bf-blender-cvs mailing list