diff --git a/source/blender/compositor/COM_realize_on_domain_operation.hh b/source/blender/compositor/COM_realize_on_domain_operation.hh index e4ae63668bb..e2f9cb9464e 100644 --- a/source/blender/compositor/COM_realize_on_domain_operation.hh +++ b/source/blender/compositor/COM_realize_on_domain_operation.hh @@ -44,10 +44,14 @@ class RealizeOnDomainOperation : public SimpleOperation { /* Given a potentially transformed domain, compute a domain such that its rotation and scale * become identity and the size of the domain is increased/reduced to adapt to the new * transformation. For instance, if the domain is rotated, the returned domain will have zero - * rotation but expanded size to account for the bounding box of the domain after rotation. The - * size of the returned domain is bound and clipped by the maximum possible size to avoid - * allocations that surpass hardware limits. */ - static Domain compute_realized_transformation_domain(Context &context, const Domain &domain); + * rotation but expanded size to account for the bounding box of the domain after rotation. + * Similarly, if the realize_translation argument is true, translation will be set to zero, + * though this will not affect the size of the domain in any way. The size of the returned domain + * is bound and clipped by the maximum possible size to avoid allocations that surpass hardware + * limits. */ + static Domain compute_realized_transformation_domain(Context &context, + const Domain &domain, + const bool realize_translation = false); protected: /* The operation domain is just the target domain. */ diff --git a/source/blender/compositor/intern/realize_on_domain_operation.cc b/source/blender/compositor/intern/realize_on_domain_operation.cc index d7bc5338bac..e5bcd1a55c5 100644 --- a/source/blender/compositor/intern/realize_on_domain_operation.cc +++ b/source/blender/compositor/intern/realize_on_domain_operation.cc @@ -207,16 +207,19 @@ Domain RealizeOnDomainOperation::compute_domain() * realization shouldn't be needed. */ static constexpr float transformation_tolerance = 10e-6f; -Domain RealizeOnDomainOperation::compute_realized_transformation_domain(Context &context, - const Domain &domain) +Domain RealizeOnDomainOperation::compute_realized_transformation_domain( + Context &context, const Domain &domain, const bool realize_translation) { const int2 size = domain.size; /* If the domain is only infinitesimally rotated or scaled, return a domain with just the - * translation component. */ + * translation component if not realizing translation. */ if (math::is_equal( float2x2(domain.transformation), float2x2::identity(), transformation_tolerance)) { + if (realize_translation) { + return Domain(size); + } return Domain(size, math::from_location(domain.transformation.location())); } @@ -263,7 +266,10 @@ Domain RealizeOnDomainOperation::compute_realized_transformation_domain(Context const int2 safe_size = math::clamp(new_size, int2(1), int2(max_size)); /* Create a domain from the new safe size and just the translation component of the - * transformation, */ + * transformation if not realizing translation. */ + if (realize_translation) { + return Domain(safe_size); + } return Domain(safe_size, math::from_location(domain.transformation.location())); } @@ -295,8 +301,11 @@ SimpleOperation *RealizeOnDomainOperation::construct_if_needed( InputRealizationMode::OperationDomain; const Domain target_domain = use_operation_domain ? operation_domain : input_result.domain(); + const bool should_realize_translation = input_descriptor.realization_mode == + InputRealizationMode::Transforms; const Domain realized_target_domain = - RealizeOnDomainOperation::compute_realized_transformation_domain(context, target_domain); + RealizeOnDomainOperation::compute_realized_transformation_domain( + context, target_domain, should_realize_translation); /* The input have an almost identical domain to the realized target domain, so no need to realize * it and the operation is not needed. */ diff --git a/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc b/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc index 773fbf5ebca..52e5681b8a1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc +++ b/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc @@ -425,6 +425,15 @@ class CornerPinOperation : public NodeOperation { return is_clipped_x || is_clipped_y || output_needed || use_anisotropic; } + + Domain compute_domain() override + { + Domain domain = this->get_input("Image").domain(); + /* Reset the location of the domain such that translations take effect, this will result in + * clipping but is more expected for the user. */ + domain.transformation.location() = float2(0.0f); + return domain; + } }; static NodeOperation *get_compositor_operation(Context &context, DNode node) diff --git a/source/blender/nodes/composite/nodes/node_composite_file_output.cc b/source/blender/nodes/composite/nodes/node_composite_file_output.cc index 11c626d1fc8..cde891373c0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_file_output.cc +++ b/source/blender/nodes/composite/nodes/node_composite_file_output.cc @@ -1023,6 +1023,19 @@ class FileOutputOperation : public NodeOperation { { return context().get_render_data().scemode & R_MULTIVIEW; } + + Domain compute_domain() override + { + Domain domain = NodeOperation::compute_domain(); + if (!this->is_multi_layer()) { + return domain; + } + + /* Reset the location of the domain in multi-layer case such that translations take effect, + * this will result in clipping but is more expected for the user. */ + domain.transformation.location() = float2(0.0f); + return domain; + } }; static NodeOperation *get_compositor_operation(Context &context, DNode node)