[Bf-blender-cvs] [313ea8a28e8] temp-compositor-canvas: Compositor: Add support for canvas compositing

Manuel Castilla noreply at git.blender.org
Sun Sep 12 20:09:30 CEST 2021


Commit: 313ea8a28e8a7a95d723fd4c46ab349ed08bea0f
Author: Manuel Castilla
Date:   Sun Sep 12 20:00:03 2021 +0200
Branches: temp-compositor-canvas
https://developer.blender.org/rB313ea8a28e8a7a95d723fd4c46ab349ed08bea0f

Compositor: Add support for canvas compositing

This patch adds functionality for operations that require pixels
translation or resizing on "Full Frame" mode, allowing to adjust
their canvas within the output canvas. It fixes current cropping
issues in translate, scale, rotate and transform nodes by adjusting
their canvas to the result, instead of the input canvas.
Only the scale node canvas is limited to the scene output
resolution size for performance reasons as there are many
operations that require their whole input to be rendered.

Operations output buffer is still always on (0,0) position for
easier image algorithm implementation, even when operation
canvas is not.

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

M	source/blender/compositor/intern/COM_CompositorContext.cc
M	source/blender/compositor/intern/COM_CompositorContext.h
M	source/blender/compositor/intern/COM_Converter.cc
M	source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
M	source/blender/compositor/intern/COM_FullFrameExecutionModel.h
M	source/blender/compositor/intern/COM_MemoryBuffer.cc
M	source/blender/compositor/intern/COM_MemoryBuffer.h
M	source/blender/compositor/intern/COM_NodeOperation.cc
M	source/blender/compositor/intern/COM_NodeOperation.h
M	source/blender/compositor/intern/COM_NodeOperationBuilder.cc
M	source/blender/compositor/intern/COM_SharedOperationBuffers.cc
M	source/blender/compositor/intern/COM_SharedOperationBuffers.h
M	source/blender/compositor/nodes/COM_BoxMaskNode.cc
M	source/blender/compositor/nodes/COM_EllipseMaskNode.cc
M	source/blender/compositor/nodes/COM_ScaleNode.cc
M	source/blender/compositor/nodes/COM_Stabilize2dNode.cc
M	source/blender/compositor/nodes/COM_TransformNode.cc
M	source/blender/compositor/nodes/COM_TranslateNode.cc
M	source/blender/compositor/operations/COM_BokehBlurOperation.cc
M	source/blender/compositor/operations/COM_CalculateMeanOperation.cc
M	source/blender/compositor/operations/COM_CropOperation.cc
M	source/blender/compositor/operations/COM_MapUVOperation.cc
M	source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
M	source/blender/compositor/operations/COM_PreviewOperation.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
M	source/blender/compositor/operations/COM_TonemapOperation.cc
M	source/blender/compositor/operations/COM_TransformOperation.cc
M	source/blender/compositor/operations/COM_TransformOperation.h
M	source/blender/compositor/operations/COM_TranslateOperation.cc
M	source/blender/compositor/operations/COM_TranslateOperation.h
M	source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc

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

diff --git a/source/blender/compositor/intern/COM_CompositorContext.cc b/source/blender/compositor/intern/COM_CompositorContext.cc
index a93820b66dc..0602553ca12 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.cc
+++ b/source/blender/compositor/intern/COM_CompositorContext.cc
@@ -43,6 +43,16 @@ int CompositorContext::getFramenumber() const
   return m_rd->cfra;
 }
 
+float CompositorContext::get_render_width() const
+{
+  return getRenderData()->xsch * getRenderPercentageAsFactor();
+}
+
+float CompositorContext::get_render_height() const
+{
+  return getRenderData()->ysch * getRenderPercentageAsFactor();
+}
+
 eExecutionModel CompositorContext::get_execution_model() const
 {
   if (U.experimental.use_full_frame_compositor) {
diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h
index c6e83f93777..088883a2f46 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.h
+++ b/source/blender/compositor/intern/COM_CompositorContext.h
@@ -288,6 +288,9 @@ class CompositorContext {
     return m_rd->size * 0.01f;
   }
 
+  float get_render_width() const;
+  float get_render_height() const;
+
   /**
    * Get active execution model.
    */
diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc
index bd05a8e4ef0..f1634f46d2b 100644
--- a/source/blender/compositor/intern/COM_Converter.cc
+++ b/source/blender/compositor/intern/COM_Converter.cc
@@ -467,7 +467,9 @@ void COM_convert_canvas(NodeOperationBuilder &builder,
   /* Data type conversions are executed before resolutions to ensure convert operations have
    * resolution. This method have to ensure same datatypes are linked for new operations. */
   BLI_assert(fromSocket->getDataType() == toSocket->getDataType());
+
   ResizeMode mode = toSocket->getResizeMode();
+  BLI_assert(mode != ResizeMode::None);
 
   NodeOperation *toOperation = &toSocket->getOperation();
   const float toWidth = toOperation->getWidth();
@@ -477,13 +479,12 @@ void COM_convert_canvas(NodeOperationBuilder &builder,
   const float fromHeight = fromOperation->getHeight();
   bool doCenter = false;
   bool doScale = false;
-  float addX = (toWidth - fromWidth) / 2.0f;
-  float addY = (toHeight - fromHeight) / 2.0f;
   float scaleX = 0;
   float scaleY = 0;
 
   switch (mode) {
     case ResizeMode::None:
+    case ResizeMode::Align:
       break;
     case ResizeMode::Center:
       doCenter = true;
@@ -518,63 +519,67 @@ void COM_convert_canvas(NodeOperationBuilder &builder,
       break;
   }
 
-  if (doCenter) {
-    NodeOperation *first = nullptr;
-    ScaleOperation *scaleOperation = nullptr;
-    if (doScale) {
-      scaleOperation = new ScaleRelativeOperation(fromSocket->getDataType());
-      scaleOperation->getInputSocket(1)->setResizeMode(ResizeMode::None);
-      scaleOperation->getInputSocket(2)->setResizeMode(ResizeMode::None);
-      first = scaleOperation;
-      SetValueOperation *sxop = new SetValueOperation();
-      sxop->setValue(scaleX);
-      builder.addLink(sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
-      SetValueOperation *syop = new SetValueOperation();
-      syop->setValue(scaleY);
-      builder.addLink(syop->getOutputSocket(), scaleOperation->getInputSocket(2));
-      builder.addOperation(sxop);
-      builder.addOperation(syop);
-
-      const rcti &scale_canvas = fromOperation->get_canvas();
-      scaleOperation->set_canvas(scale_canvas);
-      sxop->set_canvas(scale_canvas);
-      syop->set_canvas(scale_canvas);
-      builder.addOperation(scaleOperation);
-    }
+  NodeOperation *first = nullptr;
+  ScaleOperation *scaleOperation = nullptr;
+  if (doScale) {
+    scaleOperation = new ScaleRelativeOperation(fromSocket->getDataType());
+    scaleOperation->getInputSocket(1)->setResizeMode(ResizeMode::None);
+    scaleOperation->getInputSocket(2)->setResizeMode(ResizeMode::None);
+    first = scaleOperation;
+    SetValueOperation *sxop = new SetValueOperation();
+    sxop->setValue(scaleX);
+    builder.addLink(sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
+    SetValueOperation *syop = new SetValueOperation();
+    syop->setValue(scaleY);
+    builder.addLink(syop->getOutputSocket(), scaleOperation->getInputSocket(2));
+    builder.addOperation(sxop);
+    builder.addOperation(syop);
 
-    TranslateOperation *translateOperation = new TranslateOperation(toSocket->getDataType());
-    translateOperation->getInputSocket(1)->setResizeMode(ResizeMode::None);
-    translateOperation->getInputSocket(2)->setResizeMode(ResizeMode::None);
-    if (!first) {
-      first = translateOperation;
-    }
-    SetValueOperation *xop = new SetValueOperation();
-    xop->setValue(addX);
-    builder.addLink(xop->getOutputSocket(), translateOperation->getInputSocket(1));
-    SetValueOperation *yop = new SetValueOperation();
-    yop->setValue(addY);
-    builder.addLink(yop->getOutputSocket(), translateOperation->getInputSocket(2));
-    builder.addOperation(xop);
-    builder.addOperation(yop);
+    const rcti &scale_canvas = fromOperation->get_canvas();
+    scaleOperation->set_canvas(scale_canvas);
+    sxop->set_canvas(scale_canvas);
+    syop->set_canvas(scale_canvas);
+    builder.addOperation(scaleOperation);
+  }
 
-    const rcti &translate_canvas = toOperation->get_canvas();
-    translateOperation->set_canvas(translate_canvas);
-    xop->set_canvas(translate_canvas);
-    yop->set_canvas(translate_canvas);
-    builder.addOperation(translateOperation);
+  TranslateOperation *translateOperation = new TranslateOperation(toSocket->getDataType());
+  translateOperation->getInputSocket(1)->setResizeMode(ResizeMode::None);
+  translateOperation->getInputSocket(2)->setResizeMode(ResizeMode::None);
+  if (!first) {
+    first = translateOperation;
+  }
+  const float addX = doCenter ? (toWidth - fromWidth) / 2.0f : 0.0f;
+  const float addY = doCenter ? (toHeight - fromHeight) / 2.0f : 0.0f;
+  SetValueOperation *xop = new SetValueOperation();
+  xop->setValue(addX);
+  builder.addLink(xop->getOutputSocket(), translateOperation->getInputSocket(1));
+  SetValueOperation *yop = new SetValueOperation();
+  yop->setValue(addY);
+  builder.addLink(yop->getOutputSocket(), translateOperation->getInputSocket(2));
+  builder.addOperation(xop);
+  builder.addOperation(yop);
 
-    if (doScale) {
-      translateOperation->getInputSocket(0)->setResizeMode(ResizeMode::None);
-      builder.addLink(scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
-    }
+  rcti translate_canvas = toOperation->get_canvas();
+  if (mode == ResizeMode::Align) {
+    translate_canvas.xmax = translate_canvas.xmin + fromWidth;
+    translate_canvas.ymax = translate_canvas.ymin + fromHeight;
+  }
+  translateOperation->set_canvas(translate_canvas);
+  xop->set_canvas(translate_canvas);
+  yop->set_canvas(translate_canvas);
+  builder.addOperation(translateOperation);
 
-    /* remove previous link and replace */
-    builder.removeInputLink(toSocket);
-    first->getInputSocket(0)->setResizeMode(ResizeMode::None);
-    toSocket->setResizeMode(ResizeMode::None);
-    builder.addLink(fromSocket, first->getInputSocket(0));
-    builder.addLink(translateOperation->getOutputSocket(), toSocket);
+  if (doScale) {
+    translateOperation->getInputSocket(0)->setResizeMode(ResizeMode::None);
+    builder.addLink(scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
   }
+
+  /* remove previous link and replace */
+  builder.removeInputLink(toSocket);
+  first->getInputSocket(0)->setResizeMode(ResizeMode::None);
+  toSocket->setResizeMode(ResizeMode::None);
+  builder.addLink(fromSocket, first->getInputSocket(0));
+  builder.addLink(translateOperation->getOutputSocket(), toSocket);
 }
 
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
index 957bbe24e5f..c44a168390b 100644
--- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
@@ -74,34 +74,61 @@ void FullFrameExecutionModel::determine_areas_to_render_and_reads()
   }
 }
 
-Vector<MemoryBuffer *> FullFrameExecutionModel::get_input_buffers(NodeOperation *op)
+/**
+ * Returns input buffers with an offset relative to given output coordinates. Returned memory
+ * buffers must be deleted.
+ */
+Vector<MemoryBuffer *> FullFrameExecutionModel::get_input_buffers(NodeOperation *op,
+                                                                  const int output_x,
+                                                                  const int output_y)
 {
   const int num_inputs = op->getNumberOfInputSockets();
   Vector<MemoryBuffer *> inputs_buffers(num_inputs);
   for (int i = 0; i < num_inputs; i++) {
-    NodeOperation *input_op = op->get_input_operation(i);
-    inputs_buffers[i] = active_buffers_.get_rendered_buffer(input_op);
+    NodeOperation *input = op->get_input_operation(i);
+    const int offset_x = (input->get_canvas().xmin - op->get_canvas().xmin) + output_x;
+    const int offset_y = (input->get_canvas().ymin - op->get_canvas().ymin) + output_y;
+    MemoryBuffer *buf = active_buffers_.get_rendered_buffer(input);
+
+    rcti rect = buf->get_rect();
+    BLI_rcti_translate(&rect, offset_x, offset_y);
+    inputs_buffers[i] = new MemoryBuffer(
+        buf->getBuffer(), buf->get_num_channels(), rect, buf->is_a_single_elem());
   }
   return inputs_buffers;
 }
 
-MemoryBuffer *FullFrameExecutionModel::create_operation_buffer(NodeOperation *op)
+MemoryBuffer *FullFrameExecutionModel::create_operation_buffer(NodeOperation *op,
+                                                               const int output_x,
+                                                               const int output_y)
 {
+  rcti rect;
+  BLI_rcti_init(&rect, output_x, output_x + op->getWidth(), output_y, output_y + op->getHeight());
+
   const DataType data_type = op->getOutputSocket(0)->getDataType();
   const bool is_a_single_elem = op->get_flags().is_constant_operation;
- 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list