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_RotateOperation.cc')
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.cc86
1 files changed, 83 insertions, 3 deletions
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index 4fb3d324992..e3c482c15cb 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,50 @@ RotateOperation::RotateOperation()
this->m_degreeSocket = nullptr;
this->m_doDegree2RadConversion = false;
this->m_isDegreeSet = false;
+ sampler_ = PixelSampler::Bilinear;
+}
+
+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;
+ 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 +89,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(DEGREE_INPUT_INDEX);
+ 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 +159,33 @@ 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 == DEGREE_INPUT_INDEX) {
+ /* Degrees input is always used as constant. */
+ r_input_area = COM_SINGLE_ELEM_AREA;
+ return;
+ }
+
+ ensureDegree();
+ 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_);
+}
+
+void RotateOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ ensureDegree();
+ const MemoryBuffer *input_img = inputs[IMAGE_INPUT_INDEX];
+ for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+ 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);
+ }
+}
+
} // namespace blender::compositor