diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 4a8f276ddc5..556a7dc354b 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -7,10 +7,7 @@ add_subdirectory(realtime_compositor) if(WITH_COMPOSITOR_CPU) set(INC . - algorithms intern - nodes - operations realtime_compositor ../blenkernel ../blentranslation @@ -33,535 +30,8 @@ if(WITH_COMPOSITOR_CPU) set(SRC COM_compositor.hh - COM_defines.h - intern/COM_BufferArea.h - intern/COM_BufferRange.h - intern/COM_BuffersIterator.h - intern/COM_CPUDevice.cc - intern/COM_CPUDevice.h - intern/COM_CompositorContext.cc - intern/COM_CompositorContext.h - intern/COM_ConstantFolder.cc - intern/COM_ConstantFolder.h - intern/COM_Converter.cc - intern/COM_Converter.h - intern/COM_Debug.cc - intern/COM_Debug.h - intern/COM_Device.cc - intern/COM_Device.h - intern/COM_Enums.cc - intern/COM_Enums.h - intern/COM_ExecutionModel.cc - intern/COM_ExecutionModel.h - intern/COM_ExecutionSystem.cc - intern/COM_ExecutionSystem.h - intern/COM_FullFrameExecutionModel.cc - intern/COM_FullFrameExecutionModel.h - intern/COM_MemoryBuffer.cc - intern/COM_MemoryBuffer.h - intern/COM_MetaData.cc - intern/COM_MetaData.h - intern/COM_MultiThreadedOperation.cc - intern/COM_MultiThreadedOperation.h - intern/COM_MultiThreadedRowOperation.cc - intern/COM_MultiThreadedRowOperation.h - intern/COM_Node.cc - intern/COM_Node.h - intern/COM_NodeConverter.cc - intern/COM_NodeConverter.h - intern/COM_NodeGraph.cc - intern/COM_NodeGraph.h - intern/COM_NodeOperation.cc - intern/COM_NodeOperation.h - intern/COM_NodeOperationBuilder.cc - intern/COM_NodeOperationBuilder.h - intern/COM_SharedOperationBuffers.cc - intern/COM_SharedOperationBuffers.h - intern/COM_WorkPackage.h - intern/COM_WorkScheduler.cc - intern/COM_WorkScheduler.h intern/COM_compositor.cc - - # Internal nodes - nodes/COM_SocketProxyNode.cc - nodes/COM_SocketProxyNode.h - - # input nodes - nodes/COM_BokehImageNode.cc - nodes/COM_BokehImageNode.h - nodes/COM_ColorNode.cc - nodes/COM_ColorNode.h - nodes/COM_ImageNode.cc - nodes/COM_ImageNode.h - nodes/COM_MaskNode.cc - nodes/COM_MaskNode.h - nodes/COM_MovieClipNode.cc - nodes/COM_MovieClipNode.h - nodes/COM_RenderLayersNode.cc - nodes/COM_RenderLayersNode.h - nodes/COM_SceneTimeNode.cc - nodes/COM_SceneTimeNode.h - nodes/COM_SplitNode.cc - nodes/COM_SplitNode.h - nodes/COM_SwitchNode.cc - nodes/COM_SwitchNode.h - nodes/COM_SwitchViewNode.cc - nodes/COM_SwitchViewNode.h - nodes/COM_TextureNode.cc - nodes/COM_TextureNode.h - nodes/COM_TimeNode.cc - nodes/COM_TimeNode.h - nodes/COM_ValueNode.cc - nodes/COM_ValueNode.h - - # output nodes - nodes/COM_CompositorNode.cc - nodes/COM_CompositorNode.h - nodes/COM_FileOutputNode.cc - nodes/COM_FileOutputNode.h - nodes/COM_ViewLevelsNode.cc - nodes/COM_ViewLevelsNode.h - nodes/COM_ViewerNode.cc - nodes/COM_ViewerNode.h - operations/COM_CalculateMeanOperation.cc - operations/COM_CalculateMeanOperation.h - operations/COM_CalculateStandardDeviationOperation.cc - operations/COM_CalculateStandardDeviationOperation.h - - # distort nodes - nodes/COM_FlipNode.cc - nodes/COM_FlipNode.h - nodes/COM_RotateNode.cc - nodes/COM_RotateNode.h - nodes/COM_ScaleNode.cc - nodes/COM_ScaleNode.h - nodes/COM_TranslateNode.cc - nodes/COM_TranslateNode.h - - nodes/COM_DisplaceNode.cc - nodes/COM_DisplaceNode.h - nodes/COM_MapUVNode.cc - nodes/COM_MapUVNode.h - - nodes/COM_ChannelMatteNode.cc - nodes/COM_ChannelMatteNode.h - nodes/COM_ChromaMatteNode.cc - nodes/COM_ChromaMatteNode.h - nodes/COM_ColorMatteNode.cc - nodes/COM_ColorMatteNode.h - nodes/COM_DifferenceMatteNode.cc - nodes/COM_DifferenceMatteNode.h - nodes/COM_DistanceMatteNode.cc - nodes/COM_DistanceMatteNode.h - nodes/COM_LensDistortionNode.cc - nodes/COM_LensDistortionNode.h - nodes/COM_LuminanceMatteNode.cc - nodes/COM_LuminanceMatteNode.h - - nodes/COM_GlareNode.cc - nodes/COM_GlareNode.h - - nodes/COM_SunBeamsNode.cc - nodes/COM_SunBeamsNode.h - operations/COM_SunBeamsOperation.cc - operations/COM_SunBeamsOperation.h - - nodes/COM_CryptomatteNode.cc - nodes/COM_CryptomatteNode.h - operations/COM_CryptomatteOperation.cc - operations/COM_CryptomatteOperation.h - - nodes/COM_CornerPinNode.cc - nodes/COM_CornerPinNode.h - nodes/COM_PlaneTrackDeformNode.cc - nodes/COM_PlaneTrackDeformNode.h - - nodes/COM_CropNode.cc - nodes/COM_CropNode.h - operations/COM_CropOperation.cc - operations/COM_CropOperation.h - - nodes/COM_DefocusNode.cc - nodes/COM_DefocusNode.h - nodes/COM_MovieDistortionNode.cc - nodes/COM_MovieDistortionNode.h - nodes/COM_Stabilize2dNode.cc - nodes/COM_Stabilize2dNode.h - nodes/COM_TransformNode.cc - nodes/COM_TransformNode.h - - # color nodes - nodes/COM_AlphaOverNode.cc - nodes/COM_AlphaOverNode.h - nodes/COM_BrightnessNode.cc - nodes/COM_BrightnessNode.h - nodes/COM_ColorBalanceNode.cc - nodes/COM_ColorBalanceNode.h - nodes/COM_ColorCorrectionNode.cc - nodes/COM_ColorCorrectionNode.h - nodes/COM_ColorCurveNode.cc - nodes/COM_ColorCurveNode.h - nodes/COM_ColorExposureNode.cc - nodes/COM_ColorExposureNode.h - nodes/COM_ColorRampNode.cc - nodes/COM_ColorRampNode.h - nodes/COM_ColorToBWNode.cc - nodes/COM_ColorToBWNode.h - nodes/COM_ConvertAlphaNode.cc - nodes/COM_ConvertAlphaNode.h - nodes/COM_ConvertColorSpaceNode.cc - nodes/COM_ConvertColorSpaceNode.h - nodes/COM_GammaNode.cc - nodes/COM_GammaNode.h - nodes/COM_HueSaturationValueCorrectNode.cc - nodes/COM_HueSaturationValueCorrectNode.h - nodes/COM_HueSaturationValueNode.cc - nodes/COM_HueSaturationValueNode.h - nodes/COM_InvertNode.cc - nodes/COM_InvertNode.h - nodes/COM_MixNode.cc - nodes/COM_MixNode.h - nodes/COM_SetAlphaNode.cc - nodes/COM_SetAlphaNode.h - nodes/COM_TonemapNode.cc - nodes/COM_TonemapNode.h - nodes/COM_VectorCurveNode.cc - nodes/COM_VectorCurveNode.h - nodes/COM_ZCombineNode.cc - nodes/COM_ZCombineNode.h - operations/COM_TonemapOperation.cc - operations/COM_TonemapOperation.h - - # converter nodes - nodes/COM_CombineColorNode.cc - nodes/COM_CombineColorNode.h - nodes/COM_CombineColorNodeLegacy.cc - nodes/COM_CombineColorNodeLegacy.h - nodes/COM_CombineXYZNode.cc - nodes/COM_CombineXYZNode.h - nodes/COM_IDMaskNode.cc - nodes/COM_IDMaskNode.h - nodes/COM_SeparateColorNode.cc - nodes/COM_SeparateColorNode.h - nodes/COM_SeparateColorNodeLegacy.cc - nodes/COM_SeparateColorNodeLegacy.h - nodes/COM_SeparateXYZNode.cc - nodes/COM_SeparateXYZNode.h - - nodes/COM_MapRangeNode.cc - nodes/COM_MapRangeNode.h - nodes/COM_MapValueNode.cc - nodes/COM_MapValueNode.h - nodes/COM_MathNode.cc - nodes/COM_MathNode.h - nodes/COM_NormalNode.cc - nodes/COM_NormalNode.h - nodes/COM_NormalizeNode.cc - nodes/COM_NormalizeNode.h - - operations/COM_NormalizeOperation.cc - operations/COM_NormalizeOperation.h - - nodes/COM_PixelateNode.cc - nodes/COM_PixelateNode.h - operations/COM_PixelateOperation.cc - operations/COM_PixelateOperation.h - - # Filter nodes - nodes/COM_BilateralBlurNode.cc - nodes/COM_BilateralBlurNode.h - operations/COM_BilateralBlurOperation.cc - operations/COM_BilateralBlurOperation.h - nodes/COM_VectorBlurNode.cc - nodes/COM_VectorBlurNode.h - operations/COM_VectorBlurOperation.cc - operations/COM_VectorBlurOperation.h - nodes/COM_AntiAliasingNode.cc - nodes/COM_AntiAliasingNode.h - nodes/COM_BlurNode.cc - nodes/COM_BlurNode.h - nodes/COM_BokehBlurNode.cc - nodes/COM_BokehBlurNode.h - nodes/COM_DenoiseNode.cc - nodes/COM_DenoiseNode.h - nodes/COM_DespeckleNode.cc - nodes/COM_DespeckleNode.h - nodes/COM_DilateErodeNode.cc - nodes/COM_DilateErodeNode.h - nodes/COM_DirectionalBlurNode.cc - nodes/COM_DirectionalBlurNode.h - nodes/COM_FilterNode.cc - nodes/COM_FilterNode.h - nodes/COM_InpaintNode.cc - nodes/COM_InpaintNode.h - nodes/COM_KuwaharaNode.cc - nodes/COM_KuwaharaNode.h - nodes/COM_PosterizeNode.cc - nodes/COM_PosterizeNode.h - - operations/COM_BlurBaseOperation.cc - operations/COM_BlurBaseOperation.h - operations/COM_BokehBlurOperation.cc - operations/COM_BokehBlurOperation.h - operations/COM_DirectionalBlurOperation.cc - operations/COM_DirectionalBlurOperation.h - operations/COM_FastGaussianBlurOperation.cc - operations/COM_FastGaussianBlurOperation.h - operations/COM_GammaCorrectOperation.cc - operations/COM_GammaCorrectOperation.h - operations/COM_GaussianAlphaBlurBaseOperation.cc - operations/COM_GaussianAlphaBlurBaseOperation.h - operations/COM_GaussianBlurBaseOperation.cc - operations/COM_GaussianBlurBaseOperation.h - operations/COM_GaussianBokehBlurOperation.cc - operations/COM_GaussianBokehBlurOperation.h - operations/COM_KuwaharaAnisotropicOperation.cc - operations/COM_KuwaharaAnisotropicOperation.h - operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc - operations/COM_KuwaharaAnisotropicStructureTensorOperation.h - operations/COM_KuwaharaClassicOperation.cc - operations/COM_KuwaharaClassicOperation.h - operations/COM_MovieClipAttributeOperation.cc - operations/COM_MovieClipAttributeOperation.h - operations/COM_MovieDistortionOperation.cc - operations/COM_MovieDistortionOperation.h - operations/COM_PosterizeOperation.cc - operations/COM_PosterizeOperation.h - operations/COM_SMAAOperation.cc - operations/COM_SMAAOperation.h - operations/COM_SummedAreaTableOperation.cc - operations/COM_SummedAreaTableOperation.h - operations/COM_VariableSizeBokehBlurOperation.cc - operations/COM_VariableSizeBokehBlurOperation.h - - # Matte nodes - nodes/COM_BoxMaskNode.cc - nodes/COM_BoxMaskNode.h - nodes/COM_ColorSpillNode.cc - nodes/COM_ColorSpillNode.h - nodes/COM_DoubleEdgeMaskNode.cc - nodes/COM_DoubleEdgeMaskNode.h - nodes/COM_EllipseMaskNode.cc - nodes/COM_EllipseMaskNode.h - - operations/COM_DoubleEdgeMaskOperation.cc - operations/COM_DoubleEdgeMaskOperation.h - - - nodes/COM_KeyingScreenNode.cc - nodes/COM_KeyingScreenNode.h - operations/COM_KeyingScreenOperation.cc - operations/COM_KeyingScreenOperation.h - - nodes/COM_TrackPositionNode.cc - nodes/COM_TrackPositionNode.h - operations/COM_TrackPositionOperation.cc - operations/COM_TrackPositionOperation.h - - nodes/COM_KeyingNode.cc - nodes/COM_KeyingNode.h - operations/COM_KeyingBlurOperation.cc - operations/COM_KeyingBlurOperation.h - operations/COM_KeyingClipOperation.cc - operations/COM_KeyingClipOperation.h - operations/COM_KeyingDespillOperation.cc - operations/COM_KeyingDespillOperation.h - operations/COM_KeyingOperation.cc - operations/COM_KeyingOperation.h - - operations/COM_ColorSpillOperation.cc - operations/COM_ColorSpillOperation.h - operations/COM_RenderLayersProg.cc - operations/COM_RenderLayersProg.h - - operations/COM_BokehImageOperation.cc - operations/COM_BokehImageOperation.h - operations/COM_ImageOperation.cc - operations/COM_ImageOperation.h - operations/COM_MultilayerImageOperation.cc - operations/COM_MultilayerImageOperation.h - operations/COM_TextureOperation.cc - operations/COM_TextureOperation.h - - - operations/COM_SocketProxyOperation.cc - operations/COM_SocketProxyOperation.h - - operations/COM_CompositorOperation.cc - operations/COM_CompositorOperation.h - operations/COM_ConvertDepthToRadiusOperation.cc - operations/COM_ConvertDepthToRadiusOperation.h - operations/COM_FileOutputOperation.cc - operations/COM_FileOutputOperation.h - operations/COM_PreviewOperation.cc - operations/COM_PreviewOperation.h - operations/COM_SplitOperation.cc - operations/COM_SplitOperation.h - operations/COM_ViewerOperation.cc - operations/COM_ViewerOperation.h - operations/COM_ZCombineOperation.cc - operations/COM_ZCombineOperation.h - - operations/COM_ChangeHSVOperation.cc - operations/COM_ChangeHSVOperation.h - operations/COM_ChannelMatteOperation.cc - operations/COM_ChannelMatteOperation.h - operations/COM_ChromaMatteOperation.cc - operations/COM_ChromaMatteOperation.h - operations/COM_ColorCurveOperation.cc - operations/COM_ColorCurveOperation.h - operations/COM_ColorExposureOperation.cc - operations/COM_ColorExposureOperation.h - operations/COM_ColorMatteOperation.cc - operations/COM_ColorMatteOperation.h - operations/COM_ColorRampOperation.cc - operations/COM_ColorRampOperation.h - operations/COM_CurveBaseOperation.cc - operations/COM_CurveBaseOperation.h - operations/COM_DifferenceMatteOperation.cc - operations/COM_DifferenceMatteOperation.h - operations/COM_DistanceRGBMatteOperation.cc - operations/COM_DistanceRGBMatteOperation.h - operations/COM_DistanceYCCMatteOperation.cc - operations/COM_DistanceYCCMatteOperation.h - operations/COM_HueSaturationValueCorrectOperation.cc - operations/COM_HueSaturationValueCorrectOperation.h - operations/COM_LuminanceMatteOperation.cc - operations/COM_LuminanceMatteOperation.h - operations/COM_VectorCurveOperation.cc - operations/COM_VectorCurveOperation.h - - operations/COM_BrightnessOperation.cc - operations/COM_BrightnessOperation.h - operations/COM_ColorCorrectionOperation.cc - operations/COM_ColorCorrectionOperation.h - operations/COM_ConstantOperation.cc - operations/COM_ConstantOperation.h - operations/COM_GammaOperation.cc - operations/COM_GammaOperation.h - operations/COM_MixOperation.cc - operations/COM_MixOperation.h - operations/COM_SetColorOperation.cc - operations/COM_SetColorOperation.h - operations/COM_SetValueOperation.cc - operations/COM_SetValueOperation.h - operations/COM_SetVectorOperation.cc - operations/COM_SetVectorOperation.h - - operations/COM_MathBaseOperation.cc - operations/COM_MathBaseOperation.h - - operations/COM_AlphaOverKeyOperation.cc - operations/COM_AlphaOverKeyOperation.h - operations/COM_AlphaOverMixedOperation.cc - operations/COM_AlphaOverMixedOperation.h - operations/COM_AlphaOverPremultiplyOperation.cc - operations/COM_AlphaOverPremultiplyOperation.h - - operations/COM_ColorBalanceASCCDLOperation.cc - operations/COM_ColorBalanceASCCDLOperation.h - operations/COM_ColorBalanceLGGOperation.cc - operations/COM_ColorBalanceLGGOperation.h - operations/COM_ColorBalanceWhitepointOperation.cc - operations/COM_ColorBalanceWhitepointOperation.h - operations/COM_InvertOperation.cc - operations/COM_InvertOperation.h - operations/COM_MapRangeOperation.cc - operations/COM_MapRangeOperation.h - operations/COM_MapValueOperation.cc - operations/COM_MapValueOperation.h - operations/COM_SetAlphaMultiplyOperation.cc - operations/COM_SetAlphaMultiplyOperation.h - operations/COM_SetAlphaReplaceOperation.cc - operations/COM_SetAlphaReplaceOperation.h - - # Distort operation - operations/COM_DisplaceOperation.cc - operations/COM_DisplaceOperation.h - operations/COM_FlipOperation.cc - operations/COM_FlipOperation.h - operations/COM_MapUVOperation.cc - operations/COM_MapUVOperation.h - operations/COM_PlaneCornerPinOperation.cc - operations/COM_PlaneCornerPinOperation.h - operations/COM_PlaneDistortCommonOperation.cc - operations/COM_PlaneDistortCommonOperation.h - operations/COM_PlaneTrackOperation.cc - operations/COM_PlaneTrackOperation.h - operations/COM_ProjectorLensDistortionOperation.cc - operations/COM_ProjectorLensDistortionOperation.h - operations/COM_RotateOperation.cc - operations/COM_RotateOperation.h - operations/COM_ScaleOperation.cc - 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 - - # Filter operations - operations/COM_ConvolutionEdgeFilterOperation.cc - operations/COM_ConvolutionEdgeFilterOperation.h - operations/COM_ConvolutionFilterOperation.cc - operations/COM_ConvolutionFilterOperation.h - operations/COM_DenoiseOperation.cc - operations/COM_DenoiseOperation.h - operations/COM_DespeckleOperation.cc - operations/COM_DespeckleOperation.h - operations/COM_DilateErodeOperation.cc - operations/COM_DilateErodeOperation.h - operations/COM_GlareBaseOperation.cc - operations/COM_GlareBaseOperation.h - operations/COM_GlareBloomOperation.cc - operations/COM_GlareBloomOperation.h - operations/COM_GlareFogGlowOperation.cc - operations/COM_GlareFogGlowOperation.h - operations/COM_GlareGhostOperation.cc - operations/COM_GlareGhostOperation.h - operations/COM_GlareSimpleStarOperation.cc - operations/COM_GlareSimpleStarOperation.h - operations/COM_GlareStreaksOperation.cc - operations/COM_GlareStreaksOperation.h - operations/COM_GlareThresholdOperation.cc - operations/COM_GlareThresholdOperation.h - operations/COM_InpaintOperation.cc - operations/COM_InpaintOperation.h - operations/COM_SetSamplerOperation.cc - operations/COM_SetSamplerOperation.h - - - # Convert operations - operations/COM_ConvertOperation.cc - operations/COM_ConvertOperation.h - operations/COM_IDMaskOperation.cc - operations/COM_IDMaskOperation.h - - operations/COM_ConvertColorSpaceOperation.cc - operations/COM_ConvertColorSpaceOperation.h - operations/COM_DotproductOperation.cc - operations/COM_DotproductOperation.h - - # Matte operation - operations/COM_BoxMaskOperation.cc - operations/COM_BoxMaskOperation.h - operations/COM_EllipseMaskOperation.cc - operations/COM_EllipseMaskOperation.h - - operations/COM_ConvertColorProfileOperation.cc - operations/COM_ConvertColorProfileOperation.h - operations/COM_MovieClipOperation.cc - operations/COM_MovieClipOperation.h - - operations/COM_MaskOperation.cc - operations/COM_MaskOperation.h - - algorithms/COM_JumpFloodingAlgorithm.cc - algorithms/COM_JumpFloodingAlgorithm.h - algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.cc - algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.h ) set(LIB @@ -610,30 +80,10 @@ if(WITH_COMPOSITOR_CPU) blender_set_target_unity_build(bf_compositor 10) - if(COMMAND target_precompile_headers) - target_precompile_headers(bf_compositor PRIVATE COM_precomp.h) - endif() - if(CXX_WARN_NO_SUGGEST_OVERRIDE) target_compile_options(bf_compositor PRIVATE "-Wsuggest-override") endif() - if(WITH_GTESTS) - set(TEST_SRC - tests/COM_BufferArea_test.cc - tests/COM_BufferRange_test.cc - tests/COM_BuffersIterator_test.cc - tests/COM_ComputeSummedAreaTableOperation_test.cc - tests/COM_NodeOperation_test.cc - ) - set(TEST_INC - ) - set(TEST_LIB - bf_compositor - ) - blender_add_test_suite_lib(compositor "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") - endif() - # RNA_prototypes.hh add_dependencies(bf_compositor bf_rna) diff --git a/source/blender/compositor/COM_compositor.hh b/source/blender/compositor/COM_compositor.hh index 37151364da4..8da06d95e52 100644 --- a/source/blender/compositor/COM_compositor.hh +++ b/source/blender/compositor/COM_compositor.hh @@ -14,54 +14,6 @@ class Profiler; struct Render; -/* Keep ascii art. */ -/* clang-format off */ - -/** - * \defgroup Model The data model of the compositor - * \ingroup compositor - * \defgroup Memory The memory management stuff - * \ingroup compositor - * \defgroup Execution The execution logic - * \ingroup compositor - * \defgroup Conversion Conversion logic - * \ingroup compositor - * \defgroup Node All nodes of the compositor - * \ingroup compositor - * \defgroup Operation All operations of the compositor - * \ingroup compositor - * - * \section priority Render priority - * Render priority is an priority of an output node. - * A user has a different need of Render priorities of output nodes - * than during editing. - * for example. the Active ViewerNode has top priority during editing, - * but during rendering a CompositeNode has. - * All NodeOperation has a setting for their render-priority, - * but only for output NodeOperation these have effect. - * In ExecutionSystem.execute all priorities are checked. - * - * \section workscheduler WorkScheduler - * the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler - * is to balance WorkPackages to the available and free devices. - * the work-scheduler can work in 2 states. - * For witching these between the state you need to recompile blender - * - * \subsection multithread Multi threaded - * Default the work-scheduler will place all work as WorkPackage in a queue. - * For every CPUcore a working thread is created. - * These working threads will ask the WorkScheduler if there is work - * for a specific Device. - * the work-scheduler will find work for the device and the device - * will be asked to execute the WorkPackage. - * - * \subsection singlethread Single threaded - * For debugging reasons the multi-threading can be disabled. - * This is done by changing the `COM_threading_model` - * to `ThreadingModel::SingleThreaded`. When compiling the work-scheduler - * will be changes to support no threading and run everything on the CPU. - */ - /** * \brief The main method that is used to execute the compositor tree. * It can be executed during editing (`blenkernel/node.cc`) or rendering @@ -94,7 +46,6 @@ struct Render; * should be checked further, probably it'll be also needed for preview * generation in display space */ -/* clang-format on */ void COM_execute(Render *render, RenderData *render_data, diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h deleted file mode 100644 index fcd617c579f..00000000000 --- a/source/blender/compositor/COM_defines.h +++ /dev/null @@ -1,92 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_math_vector_types.hh" - -#include "DNA_vec_types.h" - -namespace blender::compositor { - -using Size2f = float2; - -enum class eDimension { X, Y }; - -/** - * \brief possible data types for sockets - * \ingroup Model - */ -enum class DataType { - /** \brief Value data type */ - Value = 0, - /** \brief Vector data type */ - Vector = 1, - /** \brief Color data type */ - Color = 2, - /** \brief Float2 data type */ - Float2 = 3, -}; - -/** - * Utility to get the number of channels of the given data type. - */ -constexpr int COM_data_type_num_channels(const DataType datatype) -{ - switch (datatype) { - case DataType::Value: - return 1; - case DataType::Float2: - return 2; - case DataType::Vector: - return 3; - case DataType::Color: - default: - return 4; - } -} - -constexpr int COM_data_type_bytes_len(DataType data_type) -{ - return COM_data_type_num_channels(data_type) * sizeof(float); -} - -constexpr int COM_DATA_TYPE_VALUE_CHANNELS = COM_data_type_num_channels(DataType::Value); -constexpr int COM_DATA_TYPE_FLOAT2_CHANNELS = COM_data_type_num_channels(DataType::Float2); -constexpr int COM_DATA_TYPE_VECTOR_CHANNELS = COM_data_type_num_channels(DataType::Vector); -constexpr int COM_DATA_TYPE_COLOR_CHANNELS = COM_data_type_num_channels(DataType::Color); - -constexpr float COM_COLOR_TRANSPARENT[4] = {0.0f, 0.0f, 0.0f, 0.0f}; -constexpr float COM_FLOAT2_ZERO[2] = {0.0f, 0.0f}; -constexpr float COM_VECTOR_ZERO[3] = {0.0f, 0.0f, 0.0f}; -constexpr float COM_COLOR_BLACK[4] = {0.0f, 0.0f, 0.0f, 1.0f}; -constexpr float COM_VALUE_ZERO[1] = {0.0f}; -constexpr float COM_VALUE_ONE[1] = {1.0f}; - -/** - * Utility to get data type for given number of channels. - */ -constexpr DataType COM_num_channels_data_type(const int num_channels) -{ - switch (num_channels) { - case 1: - return DataType::Value; - case 2: - return DataType::Float2; - case 3: - return DataType::Vector; - case 4: - default: - return DataType::Color; - } -} - -constexpr float COM_PREVIEW_SIZE = 140.f; -constexpr float COM_RULE_OF_THIRDS_DIVIDER = 100.0f; -constexpr float COM_BLUR_BOKEH_PIXELS = 512; - -constexpr rcti COM_AREA_NONE = {0, 0, 0, 0}; -constexpr rcti COM_CONSTANT_INPUT_AREA_OF_INTEREST = COM_AREA_NONE; - -} // namespace blender::compositor diff --git a/source/blender/compositor/COM_precomp.h b/source/blender/compositor/COM_precomp.h deleted file mode 100644 index e557346d3ae..00000000000 --- a/source/blender/compositor/COM_precomp.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -/* Pre-compiled headers, see: D13797. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "COM_ConstantOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_Debug.h" -#include "COM_Enums.h" -#include "COM_ExecutionSystem.h" -#include "COM_MultiThreadedOperation.h" -#include "COM_Node.h" -#include "COM_NodeOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" -#include "COM_SetColorOperation.h" -#include "COM_SetSamplerOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" -#include "COM_defines.h" diff --git a/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.cc b/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.cc deleted file mode 100644 index f24526c9107..00000000000 --- a/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -#include "BLI_array.hh" -#include "BLI_math_base.h" -#include "BLI_math_base.hh" -#include "BLI_math_vector.hh" -#include "BLI_span.hh" -#include "BLI_task.hh" - -#include "COM_JumpFloodingAlgorithm.h" - -/* Exact copies of the functions in gpu_shader_compositor_jump_flooding_lib.glsl and - * jump_flooding.cc but adapted for CPU. See those files for more information. */ - -namespace blender::compositor { - -int2 encode_jump_flooding_value(int2 closest_seed_texel, bool is_flooded) -{ - return is_flooded ? closest_seed_texel : JUMP_FLOODING_NON_FLOODED_VALUE; -} - -int2 initialize_jump_flooding_value(int2 texel, bool is_seed) -{ - return encode_jump_flooding_value(texel, is_seed); -} - -static int2 load_jump_flooding(Span input, int2 texel, int2 size, int2 fallback) -{ - if (texel.x < 0 || texel.x >= size.x || texel.y < 0 || texel.y >= size.y) { - return fallback; - } - return input[size_t(texel.y) * size.x + texel.x]; -} - -static void jump_flooding_pass(Span input, - MutableSpan output, - int2 size, - int step_size) -{ - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - - int2 closest_seed_texel = int2(0); - float minimum_squared_distance = std::numeric_limits::max(); - for (int j = -1; j <= 1; j++) { - for (int i = -1; i <= 1; i++) { - int2 offset = int2(i, j) * step_size; - - int2 fallback = JUMP_FLOODING_NON_FLOODED_VALUE; - int2 jump_flooding_value = load_jump_flooding(input, texel + offset, size, fallback); - - if (jump_flooding_value == JUMP_FLOODING_NON_FLOODED_VALUE) { - continue; - } - - int2 closest_seed_texel_to_neighbor = jump_flooding_value; - - float squared_distance = math::distance_squared(float2(closest_seed_texel_to_neighbor), - float2(texel)); - - if (squared_distance < minimum_squared_distance) { - minimum_squared_distance = squared_distance; - closest_seed_texel = closest_seed_texel_to_neighbor; - } - } - } - - bool flooding_happened = minimum_squared_distance != std::numeric_limits::max(); - int2 jump_flooding_value = encode_jump_flooding_value(closest_seed_texel, - flooding_happened); - - output[size_t(texel.y) * size.x + texel.x] = jump_flooding_value; - } - } - }); -} - -Array jump_flooding(Span input, int2 size) -{ - Array initial_flooded_result(size_t(size.x) * size.y); - jump_flooding_pass(input, initial_flooded_result, size, 1); - - Array *result_to_flood = &initial_flooded_result; - Array intermediate_result(size_t(size.x) * size.y); - Array *result_after_flooding = &intermediate_result; - - const int max_size = math::max(size.x, size.y); - int step_size = power_of_2_max_i(max_size) / 2; - - while (step_size != 0) { - jump_flooding_pass(*result_to_flood, *result_after_flooding, size, step_size); - std::swap(result_to_flood, result_after_flooding); - step_size /= 2; - } - - return *result_to_flood; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.h b/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.h deleted file mode 100644 index 2d6a26c5879..00000000000 --- a/source/blender/compositor/algorithms/COM_JumpFloodingAlgorithm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_array.hh" -#include "BLI_math_vector_types.hh" -#include "BLI_span.hh" - -/* Exact copies of the functions in gpu_shader_compositor_jump_flooding_lib.glsl and - * COM_algorithm_jump_flooding.hh but adapted for CPU. See those files for more information. */ - -#define JUMP_FLOODING_NON_FLOODED_VALUE int2(-1) - -namespace blender::compositor { - -int2 encode_jump_flooding_value(int2 closest_seed_texel, bool is_flooded); - -int2 initialize_jump_flooding_value(int2 texel, bool is_seed); - -Array jump_flooding(Span input, int2 size); - -} // namespace blender::compositor diff --git a/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.cc b/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.cc deleted file mode 100644 index dd4eee88205..00000000000 --- a/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_index_range.hh" -#include "BLI_math_base.hh" -#include "BLI_task.hh" - -#include "DNA_scene_types.h" - -#include "RE_pipeline.h" - -#include "COM_MemoryBuffer.h" -#include "COM_SymmetricSeparableBlurVariableSizeAlgorithm.h" - -namespace blender::compositor { - -static MemoryBuffer compute_symmetric_separable_blur_weights(int type, float radius) -{ - const int size = math::ceil(radius) + 1; - rcti rect; - BLI_rcti_init(&rect, 0, size, 0, 1); - MemoryBuffer weights = MemoryBuffer(DataType::Value, rect); - - float sum = 0.0f; - - const float center_weight = RE_filter_value(type, 0.0f); - *weights.get_elem(0, 0) = center_weight; - sum += center_weight; - - const float scale = radius > 0.0f ? 1.0f / radius : 0.0f; - for (const int i : IndexRange(size).drop_front(1)) { - const float weight = RE_filter_value(type, i * scale); - *weights.get_elem(i, 0) = weight; - sum += weight * 2.0f; - } - - for (const int i : IndexRange(size)) { - *weights.get_elem(i, 0) /= sum; - } - - return weights; -} - -static float sample_weight(const MemoryBuffer &weights, float parameter) -{ - const int size = weights.get_width(); - float weight; - weights.read_elem_bilinear(parameter * size, 0.0f, &weight); - return weight; -} - -static void blur_pass(const MemoryBuffer &input, - const MemoryBuffer &radius_buffer, - const MemoryBuffer &weights, - MemoryBuffer &output, - bool is_vertical) -{ - const int2 size = int2(input.get_width(), input.get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - float accumulated_weight = 0.0f; - float4 accumulated_color = float4(0.0f); - - float4 center_color = float4(input.get_elem(x, y)); - float center_weight = *weights.get_elem(0, 0); - accumulated_color += center_color * center_weight; - accumulated_weight += center_weight; - - int radius = int( - *(is_vertical ? radius_buffer.get_elem(y, x) : radius_buffer.get_elem(x, y))); - - for (int i = 1; i <= radius; i++) { - float weight = sample_weight(weights, (float(i) + 0.5f) / float(radius + 1)); - accumulated_color += float4(input.get_elem_clamped(x + i, y)) * weight; - accumulated_color += float4(input.get_elem_clamped(x - i, y)) * weight; - accumulated_weight += weight * 2.0f; - } - - const float4 final_color = accumulated_color / accumulated_weight; - copy_v4_v4(output.get_elem(y, x), final_color); - } - } - }); -} - -void symmetric_separable_blur_variable_size(const MemoryBuffer &input, - MemoryBuffer &output, - const MemoryBuffer &radius, - int filter_type, - int weights_resolution) -{ - const MemoryBuffer weights = compute_symmetric_separable_blur_weights(filter_type, - weights_resolution); - rcti rect; - BLI_rcti_init(&rect, 0, input.get_height(), 0, input.get_width()); - MemoryBuffer horizontal_pass_result = MemoryBuffer(DataType::Color, rect); - - blur_pass(input, radius, weights, horizontal_pass_result, false); - blur_pass(horizontal_pass_result, radius, weights, output, true); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.h b/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.h deleted file mode 100644 index 4083f4b3dbb..00000000000 --- a/source/blender/compositor/algorithms/COM_SymmetricSeparableBlurVariableSizeAlgorithm.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "DNA_scene_types.h" - -#include "COM_MemoryBuffer.h" - -namespace blender::compositor { - -/* Identical to the same function in COM_algorithm_symmetric_separable_blur_variable_size.hh, see - * the function and its implementation for more details. */ -void symmetric_separable_blur_variable_size(const MemoryBuffer &input, - MemoryBuffer &output, - const MemoryBuffer &radius, - int filter_type = R_FILTER_GAUSS, - int weights_resolution = 128); - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_BufferArea.h b/source/blender/compositor/intern/COM_BufferArea.h deleted file mode 100644 index 1898ddd1ab6..00000000000 --- a/source/blender/compositor/intern/COM_BufferArea.h +++ /dev/null @@ -1,201 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_assert.h" -#include "BLI_rect.h" -#include - -namespace blender::compositor { - -/* Forward declarations. */ -template class BufferAreaIterator; - -/** - * A rectangle area of buffer elements. - */ -template class BufferArea : rcti { - public: - using Iterator = BufferAreaIterator; - using ConstIterator = BufferAreaIterator; - - private: - T *buffer_; - /* Number of elements in a buffer row. */ - int buffer_width_; - /* Buffer element stride. */ - int elem_stride_; - - public: - constexpr BufferArea() = default; - - /** - * Create a buffer area containing given rectangle area. - */ - constexpr BufferArea(T *buffer, int buffer_width, const rcti &area, int elem_stride = 1) - : rcti(area), buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride) - { - } - - /** - * Create a buffer area containing whole buffer with no offsets. - */ - constexpr BufferArea(T *buffer, int buffer_width, int buffer_height, int elem_stride = 1) - : buffer_(buffer), buffer_width_(buffer_width), elem_stride_(elem_stride) - { - BLI_rcti_init(this, 0, buffer_width, 0, buffer_height); - } - - constexpr friend bool operator==(const BufferArea &a, const BufferArea &b) - { - return a.buffer_ == b.buffer_ && BLI_rcti_compare(&a, &b) && a.elem_stride_ == b.elem_stride_; - } - - constexpr const rcti &get_rect() const - { - return *this; - } - - /** - * Number of elements in a row. - */ - constexpr int width() const - { - return BLI_rcti_size_x(this); - } - - /** - * Number of elements in a column. - */ - constexpr int height() const - { - return BLI_rcti_size_y(this); - } - - constexpr Iterator begin() - { - return begin_iterator(); - } - - constexpr Iterator end() - { - return end_iterator(); - } - - constexpr ConstIterator begin() const - { - return begin_iterator(); - } - - constexpr ConstIterator end() const - { - return end_iterator(); - } - - private: - template constexpr TIterator begin_iterator() const - { - T *end_ptr = get_end_ptr(); - if (elem_stride_ == 0) { - /* Iterate a single element. */ - return TIterator(buffer_, end_ptr, 1, 1, 1); - } - - T *begin_ptr = buffer_ + (intptr_t)this->ymin * buffer_width_ * elem_stride_ + - (intptr_t)this->xmin * elem_stride_; - return TIterator(begin_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_); - } - - template constexpr TIterator end_iterator() const - { - T *end_ptr = get_end_ptr(); - if (elem_stride_ == 0) { - /* Iterate a single element. */ - return TIterator(end_ptr, end_ptr, 1, 1, 1); - } - - return TIterator(end_ptr, end_ptr, buffer_width_, BLI_rcti_size_x(this), elem_stride_); - } - - T *get_end_ptr() const - { - if (elem_stride_ == 0) { - return buffer_ + 1; - } - return buffer_ + (intptr_t)(this->ymax - 1) * buffer_width_ * elem_stride_ + - (intptr_t)this->xmax * elem_stride_; - } -}; - -template class BufferAreaIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = T *; - using pointer = T *const *; - using reference = T *const &; - using difference_type = std::ptrdiff_t; - - private: - int elem_stride_; - int row_stride_; - /* Stride between a row end and the next row start. */ - int rows_gap_; - T *current_; - const T *row_end_; - const T *end_; - - public: - constexpr BufferAreaIterator() = default; - - constexpr BufferAreaIterator( - T *current, const T *end, int buffer_width, int area_width, int elem_stride = 1) - : elem_stride_(elem_stride), - row_stride_(buffer_width * elem_stride), - rows_gap_(row_stride_ - area_width * elem_stride), - current_(current), - row_end_(current + area_width * elem_stride), - end_(end) - { - } - - constexpr BufferAreaIterator &operator++() - { - current_ += elem_stride_; - BLI_assert(current_ <= row_end_); - if (current_ == row_end_) { - BLI_assert(current_ <= end_); - if (current_ == end_) { - return *this; - } - current_ += rows_gap_; - row_end_ += row_stride_; - } - return *this; - } - - constexpr BufferAreaIterator operator++(int) const - { - BufferAreaIterator copied_iterator = *this; - ++copied_iterator; - return copied_iterator; - } - - constexpr friend bool operator!=(const BufferAreaIterator &a, const BufferAreaIterator &b) - { - return a.current_ != b.current_; - } - - constexpr friend bool operator==(const BufferAreaIterator &a, const BufferAreaIterator &b) - { - return a.current_ == b.current_; - } - - constexpr T *operator*() const - { - return current_; - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_BufferRange.h b/source/blender/compositor/intern/COM_BufferRange.h deleted file mode 100644 index b16a4003eae..00000000000 --- a/source/blender/compositor/intern/COM_BufferRange.h +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_assert.h" - -#include - -namespace blender::compositor { - -/* Forward declarations. */ -template class BufferRangeIterator; - -/** - * A range of buffer elements. - */ -template class BufferRange { - public: - using Iterator = BufferRangeIterator; - using ConstIterator = BufferRangeIterator; - - private: - T *start_; - /* Number of elements in the range. */ - int64_t size_; - /* Buffer element stride. */ - int elem_stride_; - - public: - constexpr BufferRange() = default; - - /** - * Create a buffer range of elements from a given element index. - */ - constexpr BufferRange(T *buffer, int64_t start_elem_index, int64_t size, int elem_stride = 1) - : start_(buffer + start_elem_index * elem_stride), size_(size), elem_stride_(elem_stride) - { - } - - constexpr friend bool operator==(const BufferRange &a, const BufferRange &b) - { - return a.start_ == b.start_ && a.size_ == b.size_ && a.elem_stride_ == b.elem_stride_; - } - - /** - * Access an element in the range. Index is relative to range start. - */ - constexpr T *operator[](int64_t index) const - { - BLI_assert(index >= 0); - BLI_assert(index < this->size()); - return start_ + index * elem_stride_; - } - - /** - * Get the number of elements in the range. - */ - constexpr int64_t size() const - { - return size_; - } - - constexpr Iterator begin() - { - return begin_iterator(); - } - - constexpr Iterator end() - { - return end_iterator(); - } - - constexpr ConstIterator begin() const - { - return begin_iterator(); - } - - constexpr ConstIterator end() const - { - return end_iterator(); - } - - private: - template constexpr TIterator begin_iterator() const - { - if (elem_stride_ == 0) { - /* Iterate a single element. */ - return TIterator(start_, 1); - } - - return TIterator(start_, elem_stride_); - } - - template constexpr TIterator end_iterator() const - { - if (elem_stride_ == 0) { - /* Iterate a single element. */ - return TIterator(start_ + 1, 1); - } - - return TIterator(start_ + size_ * elem_stride_, elem_stride_); - } -}; - -template class BufferRangeIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = T *; - using pointer = T *const *; - using reference = T *const &; - using difference_type = std::ptrdiff_t; - - private: - T *current_; - int elem_stride_; - - public: - constexpr BufferRangeIterator() = default; - - constexpr BufferRangeIterator(T *current, int elem_stride = 1) - : current_(current), elem_stride_(elem_stride) - { - } - - constexpr BufferRangeIterator &operator++() - { - current_ += elem_stride_; - return *this; - } - - constexpr BufferRangeIterator operator++(int) const - { - BufferRangeIterator copied_iterator = *this; - ++copied_iterator; - return copied_iterator; - } - - constexpr friend bool operator!=(const BufferRangeIterator &a, const BufferRangeIterator &b) - { - return a.current_ != b.current_; - } - - constexpr friend bool operator==(const BufferRangeIterator &a, const BufferRangeIterator &b) - { - return a.current_ == b.current_; - } - - constexpr T *operator*() const - { - return current_; - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_BuffersIterator.h b/source/blender/compositor/intern/COM_BuffersIterator.h deleted file mode 100644 index 3864749fe7e..00000000000 --- a/source/blender/compositor/intern/COM_BuffersIterator.h +++ /dev/null @@ -1,181 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_rect.h" -#include "BLI_vector.hh" - -namespace blender::compositor { - -/** - * Builds an iterator for simultaneously iterating an area of elements in an output buffer and any - * number of input buffers. It's not a standard C++ iterator and it does not support neither - * deference, equality or postfix increment operators. - */ -template class BuffersIteratorBuilder { - public: - class Iterator { - int x_start_; - int x_end_; - const T *out_end_; - int out_elem_stride_; - /* Stride between an output row end and the next row start. */ - int out_rows_gap_; - - struct In { - int elem_stride; - int rows_gap; - const T *in; - }; - Vector ins_; - - friend class BuffersIteratorBuilder; - - public: - int x; - int y; - /** Current output element. */ - T *out; - - public: - /** - * Get current element from an input. - */ - const T *in(int input_index) const - { - BLI_assert(input_index < ins_.size()); - return ins_[input_index].in; - } - - int get_num_inputs() const - { - return ins_.size(); - } - - /** - * Has the end of the area been reached. - */ - bool is_end() const - { - return out >= out_end_; - } - - /** - * Go to the next element in the area. - */ - void next() - { - out += out_elem_stride_; - for (In &in : ins_) { - in.in += in.elem_stride; - } - x++; - if (x == x_end_) { - x = x_start_; - y++; - out += out_rows_gap_; - for (In &in : ins_) { - in.in += in.rows_gap; - } - } - } - - Iterator &operator++() - { - this->next(); - return *this; - } - }; - - private: - Iterator iterator_; - rcti area_; - bool is_built_; - - public: - /** - * Create a buffers iterator builder to iterate given output buffer area. - * \param output: Output buffer. - * \param buffer_area: Whole output buffer area (may have offset position). - * \param iterated_area: Area to be iterated in all buffers. - * \param elem_stride: Output buffer element stride. - */ - BuffersIteratorBuilder(T *output, - const rcti &buffer_area, - const rcti &iterated_area, - int elem_stride = 1) - : area_(iterated_area), is_built_(false) - { - BLI_assert(BLI_rcti_inside_rcti(&buffer_area, &iterated_area)); - iterator_.x = iterated_area.xmin; - iterator_.y = iterated_area.ymin; - iterator_.x_start_ = iterated_area.xmin; - iterator_.x_end_ = iterated_area.xmax; - - iterator_.out_elem_stride_ = elem_stride; - const int buffer_width = BLI_rcti_size_x(&buffer_area); - intptr_t out_row_stride = buffer_width * elem_stride; - iterator_.out_rows_gap_ = out_row_stride - BLI_rcti_size_x(&iterated_area) * elem_stride; - const int out_start_x = iterated_area.xmin - buffer_area.xmin; - const int out_start_y = iterated_area.ymin - buffer_area.ymin; - iterator_.out = output + (intptr_t)out_start_y * out_row_stride + - (intptr_t)out_start_x * elem_stride; - const T *out_row_end_ = iterator_.out + - (intptr_t)BLI_rcti_size_x(&iterated_area) * elem_stride; - iterator_.out_end_ = out_row_end_ + - (intptr_t)out_row_stride * (BLI_rcti_size_y(&iterated_area) - 1); - } - - /** - * Create a buffers iterator builder to iterate given output buffer with no offsets. - */ - BuffersIteratorBuilder(T *output, int buffer_width, int buffer_height, int elem_stride = 1) - : BuffersIteratorBuilder(output, - {0, buffer_width, 0, buffer_height}, - {0, buffer_width, 0, buffer_height}, - elem_stride) - { - } - - /** - * Add an input buffer to be iterated. It must contain iterated area. - */ - void add_input(const T *input, const rcti &buffer_area, int elem_stride = 1) - { - BLI_assert(!is_built_); - BLI_assert(BLI_rcti_inside_rcti(&buffer_area, &area_)); - typename Iterator::In in; - in.elem_stride = elem_stride; - const size_t buffer_width = BLI_rcti_size_x(&buffer_area); - in.rows_gap = buffer_width * elem_stride - BLI_rcti_size_x(&area_) * elem_stride; - const size_t in_start_x = area_.xmin - buffer_area.xmin; - const size_t in_start_y = area_.ymin - buffer_area.ymin; - in.in = input + in_start_y * buffer_width * elem_stride + in_start_x * elem_stride; - iterator_.ins_.append(std::move(in)); - } - - /** - * Add an input buffer to be iterated with no offsets. It must contain iterated area. - */ - void add_input(const T *input, int buffer_width, int elem_stride = 1) - { - rcti buffer_area; - BLI_rcti_init(&buffer_area, 0, buffer_width, 0, area_.ymax); - add_input(input, buffer_area, elem_stride); - } - - /** - * Build the iterator. - */ - BuffersIteratorBuilder::Iterator build() - { - is_built_ = true; - return iterator_; - } -}; - -template using BuffersIterator = typename BuffersIteratorBuilder::Iterator; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_CPUDevice.cc b/source/blender/compositor/intern/COM_CPUDevice.cc deleted file mode 100644 index 6896d68c473..00000000000 --- a/source/blender/compositor/intern/COM_CPUDevice.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CPUDevice.h" - -#include "COM_WorkPackage.h" - -namespace blender::compositor { - -CPUDevice::CPUDevice(int thread_id) : thread_id_(thread_id) {} - -void CPUDevice::execute(WorkPackage *work_package) -{ - work_package->execute_fn(); - if (work_package->executed_fn) { - work_package->executed_fn(); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h deleted file mode 100644 index 8371a565982..00000000000 --- a/source/blender/compositor/intern/COM_CPUDevice.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Device.h" - -namespace blender::compositor { - -/** - * \brief class representing a CPU device. - * \note for every hardware thread in the system a CPUDevice instance - * will exist in the workscheduler. - */ -class CPUDevice : public Device { - public: - CPUDevice(int thread_id); - - /** - * \brief execute a WorkPackage - * \param work: the WorkPackage to execute - */ - void execute(WorkPackage *work) override; - - int thread_id() - { - return thread_id_; - } - - protected: - int thread_id_; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_CompositorContext.cc b/source/blender/compositor/intern/COM_CompositorContext.cc deleted file mode 100644 index 73879766177..00000000000 --- a/source/blender/compositor/intern/COM_CompositorContext.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CompositorContext.h" - -namespace blender::compositor { - -CompositorContext::CompositorContext() -{ - scene_ = nullptr; - rd_ = nullptr; - bnodetree_ = nullptr; -} - -int CompositorContext::get_framenumber() const -{ - BLI_assert(rd_); - return rd_->cfra; -} - -Size2f CompositorContext::get_render_size() const -{ - return {get_render_data()->xsch * get_render_percentage_as_factor(), - get_render_data()->ysch * get_render_percentage_as_factor()}; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h deleted file mode 100644 index 18e93057fa7..00000000000 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ /dev/null @@ -1,225 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Enums.h" - -#include "DNA_color_types.h" -#include "DNA_node_types.h" -#include "DNA_scene_types.h" - -namespace blender::bke { -struct bNodeInstanceHash; -} - -namespace blender::realtime_compositor { -class RenderContext; -class Profiler; -} // namespace blender::realtime_compositor - -namespace blender::compositor { - -/** - * \brief Overall context of the compositor - */ -class CompositorContext { - private: - /** - * \brief The rendering field describes if we are rendering (F12) or if we are editing (Node - * editor) This field is initialized in ExecutionSystem and must only be read from that point - * on. \see ExecutionSystem - */ - bool rendering_; - - Scene *scene_; - - /** - * \brief Reference to the render data that is being composited. - * This field is initialized in ExecutionSystem and must only be read from that point on. - * \see ExecutionSystem - */ - RenderData *rd_; - - /** - * \brief reference to the bNodeTree - * This field is initialized in ExecutionSystem and must only be read from that point on. - * \see ExecutionSystem - */ - bNodeTree *bnodetree_; - - /** - * \brief Preview image hash table - * This field is initialized in ExecutionSystem and must only be read from that point on. - */ - bke::bNodeInstanceHash *previews_; - - /** - * \brief active rendering view name - */ - const char *view_name_; - - /** - * \brief Render context that contains information about active render. Can be null if the - * compositor is not executing as part of the render pipeline. - */ - realtime_compositor::RenderContext *render_context_; - - /** - * \brief Profiler that stores timing information about compositor execution. Can be null if the - * compositor context does not support profiling. - */ - realtime_compositor::Profiler *profiler_; - - public: - /** - * \brief constructor initializes the context with default values. - */ - CompositorContext(); - - /** - * \brief set the rendering field of the context - */ - void set_rendering(bool rendering) - { - rendering_ = rendering; - } - - /** - * \brief get the rendering field of the context - */ - bool is_rendering() const - { - return rendering_; - } - - /** - * \brief set the scene of the context - */ - void set_render_data(RenderData *rd) - { - rd_ = rd; - } - - /** - * \brief set the bnodetree of the context - */ - void set_bnodetree(bNodeTree *bnodetree) - { - bnodetree_ = bnodetree; - } - - /** - * \brief get the bnodetree of the context - */ - const bNodeTree *get_bnodetree() const - { - return bnodetree_; - } - - /** - * \brief get the scene of the context - */ - const RenderData *get_render_data() const - { - return rd_; - } - - void set_scene(Scene *scene) - { - scene_ = scene; - } - Scene *get_scene() const - { - return scene_; - } - - /** - * \brief set the preview image hash table - */ - void set_preview_hash(bke::bNodeInstanceHash *previews) - { - previews_ = previews; - } - - /** - * \brief get the preview image hash table - */ - bke::bNodeInstanceHash *get_preview_hash() const - { - return previews_; - } - - /** - * \brief get the current frame-number of the scene in this context - */ - int get_framenumber() const; - - /** Whether it has a view with a specific name and not the default one. */ - bool has_explicit_view() const - { - return view_name_ && view_name_[0] != '\0'; - } - - /** - * \brief get the render context - */ - realtime_compositor::RenderContext *get_render_context() const - { - return render_context_; - } - - /** - * \brief set the render context - */ - void set_render_context(realtime_compositor::RenderContext *render_context) - { - render_context_ = render_context; - } - - /** - * \brief get the profiler - */ - realtime_compositor::Profiler *get_profiler() const - { - return profiler_; - } - - /** - * \brief set the profiler - */ - void set_profiler(realtime_compositor::Profiler *profiler) - { - profiler_ = profiler; - } - - /** - * \brief get the active rendering view - */ - const char *get_view_name() const - { - return view_name_; - } - - /** - * \brief set the active rendering view - */ - void set_view_name(const char *view_name) - { - view_name_ = view_name; - } - - /** - * \brief Get the render percentage as a factor. - * The compositor uses a factor i.o. a percentage. - */ - float get_render_percentage_as_factor() const - { - return rd_->size * 0.01f; - } - - Size2f get_render_size() const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ConstantFolder.cc b/source/blender/compositor/intern/COM_ConstantFolder.cc deleted file mode 100644 index d816896e928..00000000000 --- a/source/blender/compositor/intern/COM_ConstantFolder.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_map.hh" -#include "BLI_set.hh" - -#include "COM_ConstantFolder.h" -#include "COM_NodeOperationBuilder.h" -#include "COM_SetColorOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" -#include "COM_WorkScheduler.h" - -namespace blender::compositor { - -ConstantFolder::ConstantFolder(NodeOperationBuilder &operations_builder) - : operations_builder_(operations_builder) -{ - /* Use maximum render resolution. Avoid having large integers to prevent integer overflows. */ - const int max_size = 65536; - BLI_rcti_init(&max_area_, -max_size, max_size, -max_size, max_size); - BLI_rcti_init(&first_elem_area_, 0, 1, 0, 1); -} - -static bool is_constant_foldable(NodeOperation *operation) -{ - if (operation->get_flags().can_be_constant && !operation->get_flags().is_constant_operation) { - for (int i = 0; i < operation->get_number_of_input_sockets(); i++) { - NodeOperation *input = operation->get_input_operation(i); - if (!input->get_flags().is_constant_operation || - !static_cast(input)->can_get_constant_elem()) - { - return false; - } - } - return true; - } - return false; -} - -static Set find_constant_foldable_operations(Span operations) -{ - Set foldable_ops; - for (NodeOperation *op : operations) { - if (is_constant_foldable(op)) { - foldable_ops.add(op); - } - } - return foldable_ops; -} - -static ConstantOperation *create_constant_operation(DataType data_type, const float *constant_elem) -{ - switch (data_type) { - case DataType::Color: { - SetColorOperation *color_op = new SetColorOperation(); - color_op->set_channels(constant_elem); - return color_op; - } - case DataType::Vector: { - SetVectorOperation *vector_op = new SetVectorOperation(); - vector_op->set_vector(constant_elem); - return vector_op; - } - case DataType::Value: { - SetValueOperation *value_op = new SetValueOperation(); - value_op->set_value(*constant_elem); - return value_op; - } - default: { - BLI_assert_msg(0, "Non implemented data type"); - return nullptr; - } - } -} - -ConstantOperation *ConstantFolder::fold_operation(NodeOperation *operation) -{ - const DataType data_type = operation->get_output_socket()->get_data_type(); - MemoryBuffer fold_buf(data_type, first_elem_area_); - Vector input_bufs = get_constant_input_buffers(operation); - operation->init_data(); - operation->render(&fold_buf, {first_elem_area_}, input_bufs); - - MemoryBuffer *constant_buf = create_constant_buffer(data_type); - constant_buf->copy_from(&fold_buf, first_elem_area_); - ConstantOperation *constant_op = create_constant_operation(data_type, - constant_buf->get_buffer()); - operations_builder_.replace_operation_with_constant(operation, constant_op); - constant_buffers_.add_new(constant_op, constant_buf); - return constant_op; -} - -MemoryBuffer *ConstantFolder::create_constant_buffer(const DataType data_type) -{ - /* Create a single elem buffer with maximum area possible so readers can read any coordinate - * returning always same element. */ - return new MemoryBuffer(data_type, max_area_, true); -} - -Vector ConstantFolder::get_constant_input_buffers(NodeOperation *operation) -{ - const int num_inputs = operation->get_number_of_input_sockets(); - Vector inputs_bufs(num_inputs); - for (int i = 0; i < num_inputs; i++) { - BLI_assert(operation->get_input_operation(i)->get_flags().is_constant_operation); - ConstantOperation *constant_op = static_cast( - operation->get_input_operation(i)); - MemoryBuffer *constant_buf = constant_buffers_.lookup_or_add_cb(constant_op, [=] { - MemoryBuffer *buf = create_constant_buffer( - constant_op->get_output_socket()->get_data_type()); - constant_op->render(buf, {first_elem_area_}, {}); - return buf; - }); - inputs_bufs[i] = constant_buf; - } - return inputs_bufs; -} - -Vector ConstantFolder::try_fold_operations(Span operations) -{ - Set foldable_ops = find_constant_foldable_operations(operations); - if (foldable_ops.is_empty()) { - return Vector(); - } - - Vector new_folds; - for (NodeOperation *op : foldable_ops) { - ConstantOperation *constant_op = fold_operation(op); - new_folds.append(constant_op); - } - return new_folds; -} - -int ConstantFolder::fold_operations() -{ - WorkScheduler::start(); - Vector last_folds = try_fold_operations( - operations_builder_.get_operations()); - int folds_count = last_folds.size(); - while (last_folds.size() > 0) { - Vector ops_to_fold; - for (ConstantOperation *fold : last_folds) { - get_operation_output_operations(fold, ops_to_fold); - } - last_folds = try_fold_operations(ops_to_fold); - folds_count += last_folds.size(); - } - WorkScheduler::stop(); - - delete_constant_buffers(); - - return folds_count; -} - -void ConstantFolder::delete_constant_buffers() -{ - for (MemoryBuffer *buf : constant_buffers_.values()) { - delete buf; - } - constant_buffers_.clear(); -} - -void ConstantFolder::get_operation_output_operations(NodeOperation *operation, - Vector &r_outputs) -{ - const Vector &links = operations_builder_.get_links(); - for (const NodeOperationBuilder::Link &link : links) { - if (&link.from()->get_operation() == operation) { - r_outputs.append(&link.to()->get_operation()); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ConstantFolder.h b/source/blender/compositor/intern/COM_ConstantFolder.h deleted file mode 100644 index 5477a2d04d5..00000000000 --- a/source/blender/compositor/intern/COM_ConstantFolder.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_defines.h" - -namespace blender::compositor { - -class NodeOperation; -class NodeOperationBuilder; -class ConstantOperation; -class MemoryBuffer; - -/** - * Evaluates all operations with constant elements into primitive constant operations - * (Value/Vector/Color). - */ -class ConstantFolder { - private: - NodeOperationBuilder &operations_builder_; - - /** Constant operations buffers. */ - Map constant_buffers_; - - rcti max_area_; - rcti first_elem_area_; - - public: - /** - * \param operations_builder: Contains all operations to fold. - * \param exec_system: Execution system. - */ - ConstantFolder(NodeOperationBuilder &operations_builder); - /** - * Evaluate operations with constant elements into primitive constant operations. - */ - int fold_operations(); - - private: - /** Returns constant operations resulted from folded operations. */ - Vector try_fold_operations(Span operations); - ConstantOperation *fold_operation(NodeOperation *operation); - - MemoryBuffer *create_constant_buffer(DataType data_type); - Vector get_constant_input_buffers(NodeOperation *operation); - void delete_constant_buffers(); - - void get_operation_output_operations(NodeOperation *operation, - Vector &r_outputs); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc deleted file mode 100644 index 75244d86c31..00000000000 --- a/source/blender/compositor/intern/COM_Converter.cc +++ /dev/null @@ -1,587 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "DNA_node_types.h" - -#include "BKE_node.hh" - -#include "COM_NodeOperationBuilder.h" - -#include "COM_AlphaOverNode.h" -#include "COM_AntiAliasingNode.h" -#include "COM_BilateralBlurNode.h" -#include "COM_BlurNode.h" -#include "COM_BokehBlurNode.h" -#include "COM_BokehImageNode.h" -#include "COM_BoxMaskNode.h" -#include "COM_BrightnessNode.h" -#include "COM_ChannelMatteNode.h" -#include "COM_ChromaMatteNode.h" -#include "COM_ColorBalanceNode.h" -#include "COM_ColorCorrectionNode.h" -#include "COM_ColorCurveNode.h" -#include "COM_ColorExposureNode.h" -#include "COM_ColorMatteNode.h" -#include "COM_ColorNode.h" -#include "COM_ColorRampNode.h" -#include "COM_ColorSpillNode.h" -#include "COM_ColorToBWNode.h" -#include "COM_CombineColorNode.h" -#include "COM_CombineColorNodeLegacy.h" -#include "COM_CombineXYZNode.h" -#include "COM_CompositorNode.h" -#include "COM_ConvertAlphaNode.h" -#include "COM_ConvertColorSpaceNode.h" -#include "COM_ConvertOperation.h" -#include "COM_Converter.h" -#include "COM_CornerPinNode.h" -#include "COM_CropNode.h" -#include "COM_CryptomatteNode.h" -#include "COM_DefocusNode.h" -#include "COM_DenoiseNode.h" -#include "COM_DespeckleNode.h" -#include "COM_DifferenceMatteNode.h" -#include "COM_DilateErodeNode.h" -#include "COM_DirectionalBlurNode.h" -#include "COM_DisplaceNode.h" -#include "COM_DistanceMatteNode.h" -#include "COM_DoubleEdgeMaskNode.h" -#include "COM_EllipseMaskNode.h" -#include "COM_FileOutputNode.h" -#include "COM_FilterNode.h" -#include "COM_FlipNode.h" -#include "COM_GammaNode.h" -#include "COM_GlareNode.h" -#include "COM_HueSaturationValueCorrectNode.h" -#include "COM_HueSaturationValueNode.h" -#include "COM_IDMaskNode.h" -#include "COM_ImageNode.h" -#include "COM_InpaintNode.h" -#include "COM_InvertNode.h" -#include "COM_KeyingNode.h" -#include "COM_KeyingScreenNode.h" -#include "COM_KuwaharaNode.h" -#include "COM_LensDistortionNode.h" -#include "COM_LuminanceMatteNode.h" -#include "COM_MapRangeNode.h" -#include "COM_MapUVNode.h" -#include "COM_MapValueNode.h" -#include "COM_MaskNode.h" -#include "COM_MathNode.h" -#include "COM_MixNode.h" -#include "COM_MovieClipNode.h" -#include "COM_MovieDistortionNode.h" -#include "COM_NormalNode.h" -#include "COM_NormalizeNode.h" -#include "COM_PixelateNode.h" -#include "COM_PlaneTrackDeformNode.h" -#include "COM_PosterizeNode.h" -#include "COM_RenderLayersNode.h" -#include "COM_RotateNode.h" -#include "COM_ScaleNode.h" -#include "COM_ScaleOperation.h" -#include "COM_SceneTimeNode.h" -#include "COM_SeparateColorNode.h" -#include "COM_SeparateColorNodeLegacy.h" -#include "COM_SeparateXYZNode.h" -#include "COM_SetAlphaNode.h" -#include "COM_SetValueOperation.h" -#include "COM_SplitNode.h" -#include "COM_Stabilize2dNode.h" -#include "COM_SunBeamsNode.h" -#include "COM_SwitchNode.h" -#include "COM_SwitchViewNode.h" -#include "COM_TextureNode.h" -#include "COM_TimeNode.h" -#include "COM_TonemapNode.h" -#include "COM_TrackPositionNode.h" -#include "COM_TransformNode.h" -#include "COM_TranslateNode.h" -#include "COM_TranslateOperation.h" -#include "COM_ValueNode.h" -#include "COM_VectorBlurNode.h" -#include "COM_VectorCurveNode.h" -#include "COM_ViewLevelsNode.h" -#include "COM_ViewerNode.h" -#include "COM_ZCombineNode.h" - -namespace blender::compositor { - -Node *COM_convert_bnode(bNode *b_node) -{ - Node *node = nullptr; - - /* ignore undefined nodes with missing or invalid node data */ - if (blender::bke::node_type_is_undefined(b_node)) { - return nullptr; - } - - switch (b_node->type) { - case CMP_NODE_COMPOSITE: - node = new CompositorNode(b_node); - break; - case CMP_NODE_R_LAYERS: - node = new RenderLayersNode(b_node); - break; - case CMP_NODE_TEXTURE: - node = new TextureNode(b_node); - break; - case CMP_NODE_RGBTOBW: - node = new ColorToBWNode(b_node); - break; - case CMP_NODE_MIX_RGB: - node = new MixNode(b_node); - break; - case CMP_NODE_TRANSLATE: - node = new TranslateNode(b_node); - break; - case CMP_NODE_SCALE: - node = new ScaleNode(b_node); - break; - case CMP_NODE_ROTATE: - node = new RotateNode(b_node); - break; - case CMP_NODE_FLIP: - node = new FlipNode(b_node); - break; - case CMP_NODE_FILTER: - node = new FilterNode(b_node); - break; - case CMP_NODE_ID_MASK: - node = new IDMaskNode(b_node); - break; - case CMP_NODE_BRIGHTCONTRAST: - node = new BrightnessNode(b_node); - break; - case CMP_NODE_SEPARATE_COLOR: - node = new SeparateColorNode(b_node); - break; - case CMP_NODE_COMBINE_COLOR: - node = new CombineColorNode(b_node); - break; - case CMP_NODE_SEPRGBA_LEGACY: - node = new SeparateRGBANode(b_node); - break; - case CMP_NODE_COMBRGBA_LEGACY: - node = new CombineRGBANode(b_node); - break; - case CMP_NODE_SEPHSVA_LEGACY: - node = new SeparateHSVANode(b_node); - break; - case CMP_NODE_COMBHSVA_LEGACY: - node = new CombineHSVANode(b_node); - break; - case CMP_NODE_SEPYUVA_LEGACY: - node = new SeparateYUVANode(b_node); - break; - case CMP_NODE_COMBYUVA_LEGACY: - node = new CombineYUVANode(b_node); - break; - case CMP_NODE_SEPYCCA_LEGACY: - node = new SeparateYCCANode(b_node); - break; - case CMP_NODE_COMBYCCA_LEGACY: - node = new CombineYCCANode(b_node); - break; - case CMP_NODE_ALPHAOVER: - node = new AlphaOverNode(b_node); - break; - case CMP_NODE_COLORBALANCE: - node = new ColorBalanceNode(b_node); - break; - case CMP_NODE_VIEWER: - node = new ViewerNode(b_node); - break; - case CMP_NODE_SPLIT: - node = new SplitNode(b_node); - break; - case CMP_NODE_INVERT: - node = new InvertNode(b_node); - break; - case NODE_GROUP: - case NODE_GROUP_INPUT: - case NODE_GROUP_OUTPUT: - /* handled in NodeCompiler */ - break; - case CMP_NODE_NORMAL: - node = new NormalNode(b_node); - break; - case CMP_NODE_NORMALIZE: - node = new NormalizeNode(b_node); - break; - case CMP_NODE_IMAGE: - node = new ImageNode(b_node); - break; - case CMP_NODE_SETALPHA: - node = new SetAlphaNode(b_node); - break; - case CMP_NODE_PREMULKEY: - node = new ConvertAlphaNode(b_node); - break; - case CMP_NODE_MATH: - node = new MathNode(b_node); - break; - case CMP_NODE_HUE_SAT: - node = new HueSaturationValueNode(b_node); - break; - case CMP_NODE_COLORCORRECTION: - node = new ColorCorrectionNode(b_node); - break; - case CMP_NODE_MASK_BOX: - node = new BoxMaskNode(b_node); - break; - case CMP_NODE_MASK_ELLIPSE: - node = new EllipseMaskNode(b_node); - break; - case CMP_NODE_GAMMA: - node = new GammaNode(b_node); - break; - case CMP_NODE_CURVE_RGB: - node = new ColorCurveNode(b_node); - break; - case CMP_NODE_CURVE_VEC: - node = new VectorCurveNode(b_node); - break; - case CMP_NODE_HUECORRECT: - node = new HueSaturationValueCorrectNode(b_node); - break; - case CMP_NODE_MAP_UV: - node = new MapUVNode(b_node); - break; - case CMP_NODE_DISPLACE: - node = new DisplaceNode(b_node); - break; - case CMP_NODE_VALTORGB: - node = new ColorRampNode(b_node); - break; - case CMP_NODE_DIFF_MATTE: - node = new DifferenceMatteNode(b_node); - break; - case CMP_NODE_LUMA_MATTE: - node = new LuminanceMatteNode(b_node); - break; - case CMP_NODE_DIST_MATTE: - node = new DistanceMatteNode(b_node); - break; - case CMP_NODE_CHROMA_MATTE: - node = new ChromaMatteNode(b_node); - break; - case CMP_NODE_COLOR_MATTE: - node = new ColorMatteNode(b_node); - break; - case CMP_NODE_CHANNEL_MATTE: - node = new ChannelMatteNode(b_node); - break; - case CMP_NODE_BLUR: - node = new BlurNode(b_node); - break; - case CMP_NODE_BOKEHIMAGE: - node = new BokehImageNode(b_node); - break; - case CMP_NODE_BOKEHBLUR: - node = new BokehBlurNode(b_node); - break; - case CMP_NODE_DILATEERODE: - node = new DilateErodeNode(b_node); - break; - case CMP_NODE_INPAINT: - node = new InpaintNode(b_node); - break; - case CMP_NODE_DESPECKLE: - node = new DespeckleNode(b_node); - break; - case CMP_NODE_LENSDIST: - node = new LensDistortionNode(b_node); - break; - case CMP_NODE_RGB: - node = new ColorNode(b_node); - break; - case CMP_NODE_VALUE: - node = new ValueNode(b_node); - break; - case CMP_NODE_TIME: - node = new TimeNode(b_node); - break; - case CMP_NODE_DBLUR: - node = new DirectionalBlurNode(b_node); - break; - case CMP_NODE_ZCOMBINE: - node = new ZCombineNode(b_node); - break; - case CMP_NODE_TONEMAP: - node = new TonemapNode(b_node); - break; - case CMP_NODE_SWITCH: - node = new SwitchNode(b_node); - break; - case CMP_NODE_SWITCH_VIEW: - node = new SwitchViewNode(b_node); - break; - case CMP_NODE_GLARE: - node = new GlareNode(b_node); - break; - case CMP_NODE_MOVIECLIP: - node = new MovieClipNode(b_node); - break; - case CMP_NODE_COLOR_SPILL: - node = new ColorSpillNode(b_node); - break; - case CMP_NODE_OUTPUT_FILE: - node = new FileOutputNode(b_node); - break; - case CMP_NODE_MAP_VALUE: - node = new MapValueNode(b_node); - break; - case CMP_NODE_MAP_RANGE: - node = new MapRangeNode(b_node); - break; - case CMP_NODE_TRANSFORM: - node = new TransformNode(b_node); - break; - case CMP_NODE_SCENE_TIME: - node = new SceneTimeNode(b_node); - break; - case CMP_NODE_STABILIZE2D: - node = new Stabilize2dNode(b_node); - break; - case CMP_NODE_BILATERALBLUR: - node = new BilateralBlurNode(b_node); - break; - case CMP_NODE_VECBLUR: - node = new VectorBlurNode(b_node); - break; - case CMP_NODE_MOVIEDISTORTION: - node = new MovieDistortionNode(b_node); - break; - case CMP_NODE_VIEW_LEVELS: - node = new ViewLevelsNode(b_node); - break; - case CMP_NODE_DEFOCUS: - node = new DefocusNode(b_node); - break; - case CMP_NODE_DOUBLEEDGEMASK: - node = new DoubleEdgeMaskNode(b_node); - break; - case CMP_NODE_CROP: - node = new CropNode(b_node); - break; - case CMP_NODE_MASK: - node = new MaskNode(b_node); - break; - case CMP_NODE_KEYINGSCREEN: - node = new KeyingScreenNode(b_node); - break; - case CMP_NODE_KEYING: - node = new KeyingNode(b_node); - break; - case CMP_NODE_TRACKPOS: - node = new TrackPositionNode(b_node); - break; - /* not implemented yet */ - case CMP_NODE_PIXELATE: - node = new PixelateNode(b_node); - break; - case CMP_NODE_PLANETRACKDEFORM: - node = new PlaneTrackDeformNode(b_node); - break; - case CMP_NODE_CORNERPIN: - node = new CornerPinNode(b_node); - break; - case CMP_NODE_SUNBEAMS: - node = new SunBeamsNode(b_node); - break; - case CMP_NODE_CRYPTOMATTE_LEGACY: - node = new CryptomatteLegacyNode(b_node); - break; - case CMP_NODE_CRYPTOMATTE: - node = new CryptomatteNode(b_node); - break; - case CMP_NODE_DENOISE: - node = new DenoiseNode(b_node); - break; - case CMP_NODE_EXPOSURE: - node = new ExposureNode(b_node); - break; - case CMP_NODE_ANTIALIASING: - node = new AntiAliasingNode(b_node); - break; - case CMP_NODE_POSTERIZE: - node = new PosterizeNode(b_node); - break; - case CMP_NODE_CONVERT_COLOR_SPACE: - node = new ConvertColorSpaceNode(b_node); - break; - case CMP_NODE_SEPARATE_XYZ: - node = new SeparateXYZNode(b_node); - break; - case CMP_NODE_COMBINE_XYZ: - node = new CombineXYZNode(b_node); - break; - case CMP_NODE_KUWAHARA: - node = new KuwaharaNode(b_node); - break; - } - return node; -} - -NodeOperation *COM_convert_data_type(const NodeOperationOutput &from, const NodeOperationInput &to) -{ - /* TODO(jbakker): make the return value an #std::optional. */ - - const DataType src_data_type = from.get_data_type(); - const DataType dst_data_type = to.get_data_type(); - - if (src_data_type == DataType::Value && dst_data_type == DataType::Color) { - return new ConvertValueToColorOperation(); - } - if (src_data_type == DataType::Value && dst_data_type == DataType::Vector) { - return new ConvertValueToVectorOperation(); - } - if (src_data_type == DataType::Color && dst_data_type == DataType::Value) { - return new ConvertColorToValueOperation(); - } - if (src_data_type == DataType::Color && dst_data_type == DataType::Vector) { - return new ConvertColorToVectorOperation(); - } - if (src_data_type == DataType::Vector && dst_data_type == DataType::Value) { - return new ConvertVectorToValueOperation(); - } - if (src_data_type == DataType::Vector && dst_data_type == DataType::Color) { - return new ConvertVectorToColorOperation(); - } - - return nullptr; -} - -void COM_convert_canvas(NodeOperationBuilder &builder, - NodeOperationOutput *from_socket, - NodeOperationInput *to_socket) -{ - /* Data type conversions are executed before resolutions to ensure convert operations have - * resolution. This method have to ensure same data-types are linked for new operations. */ - BLI_assert(from_socket->get_data_type() == to_socket->get_data_type()); - - ResizeMode mode = to_socket->get_resize_mode(); - BLI_assert(mode != ResizeMode::None); - - NodeOperation *to_operation = &to_socket->get_operation(); - const float to_width = to_operation->get_width(); - const float to_height = to_operation->get_height(); - NodeOperation *from_operation = &from_socket->get_operation(); - const float from_width = from_operation->get_width(); - const float from_height = from_operation->get_height(); - bool do_center = false; - bool do_scale = false; - float scaleX = 0; - float scaleY = 0; - - switch (mode) { - case ResizeMode::None: - case ResizeMode::Align: - break; - case ResizeMode::Center: - do_center = true; - break; - case ResizeMode::FitWidth: - do_center = true; - do_scale = true; - scaleX = scaleY = to_width / from_width; - break; - case ResizeMode::FitHeight: - do_center = true; - do_scale = true; - scaleX = scaleY = to_height / from_height; - break; - case ResizeMode::FitAny: - do_center = true; - do_scale = true; - scaleX = to_width / from_width; - scaleY = to_height / from_height; - if (scaleX < scaleY) { - scaleX = scaleY; - } - else { - scaleY = scaleX; - } - break; - case ResizeMode::Stretch: - do_center = true; - do_scale = true; - scaleX = to_width / from_width; - scaleY = to_height / from_height; - break; - } - - float addX = do_center ? (to_width - from_width) / 2.0f : 0.0f; - float addY = do_center ? (to_height - from_height) / 2.0f : 0.0f; - NodeOperation *first = nullptr; - ScaleOperation *scale_operation = nullptr; - if (do_scale) { - scale_operation = new ScaleRelativeOperation(from_socket->get_data_type()); - scale_operation->get_input_socket(1)->set_resize_mode(ResizeMode::None); - scale_operation->get_input_socket(2)->set_resize_mode(ResizeMode::None); - first = scale_operation; - SetValueOperation *sxop = new SetValueOperation(); - sxop->set_value(scaleX); - builder.add_link(sxop->get_output_socket(), scale_operation->get_input_socket(1)); - SetValueOperation *syop = new SetValueOperation(); - syop->set_value(scaleY); - builder.add_link(syop->get_output_socket(), scale_operation->get_input_socket(2)); - builder.add_operation(sxop); - builder.add_operation(syop); - - rcti scale_canvas = from_operation->get_canvas(); - ScaleOperation::scale_area(scale_canvas, scaleX, scaleY); - scale_canvas.xmax = scale_canvas.xmin + to_operation->get_width(); - scale_canvas.ymax = scale_canvas.ymin + to_operation->get_height(); - addX = 0; - addY = 0; - scale_operation->set_canvas(scale_canvas); - sxop->set_canvas(scale_canvas); - syop->set_canvas(scale_canvas); - builder.add_operation(scale_operation); - } - - TranslateOperation *translate_operation = new TranslateOperation(to_socket->get_data_type()); - translate_operation->get_input_socket(1)->set_resize_mode(ResizeMode::None); - translate_operation->get_input_socket(2)->set_resize_mode(ResizeMode::None); - if (!first) { - first = translate_operation; - } - SetValueOperation *xop = new SetValueOperation(); - xop->set_value(addX); - builder.add_link(xop->get_output_socket(), translate_operation->get_input_socket(1)); - SetValueOperation *yop = new SetValueOperation(); - yop->set_value(addY); - builder.add_link(yop->get_output_socket(), translate_operation->get_input_socket(2)); - builder.add_operation(xop); - builder.add_operation(yop); - - rcti translate_canvas = to_operation->get_canvas(); - if (mode == ResizeMode::Align) { - translate_canvas.xmax = translate_canvas.xmin + from_width; - translate_canvas.ymax = translate_canvas.ymin + from_height; - } - translate_operation->set_canvas(translate_canvas); - xop->set_canvas(translate_canvas); - yop->set_canvas(translate_canvas); - builder.add_operation(translate_operation); - - if (do_scale) { - translate_operation->get_input_socket(0)->set_resize_mode(ResizeMode::None); - builder.add_link(scale_operation->get_output_socket(), - translate_operation->get_input_socket(0)); - } - - /* remove previous link and replace */ - builder.remove_input_link(to_socket); - first->get_input_socket(0)->set_resize_mode(ResizeMode::None); - to_socket->set_resize_mode(ResizeMode::None); - builder.add_link(from_socket, first->get_input_socket(0)); - builder.add_link(translate_operation->get_output_socket(), to_socket); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h deleted file mode 100644 index 5e0d6dee871..00000000000 --- a/source/blender/compositor/intern/COM_Converter.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "MEM_guardedalloc.h" - -struct bNode; - -namespace blender::compositor { - -class Node; -class NodeOperation; -class NodeOperationInput; -class NodeOperationOutput; -class NodeOperationBuilder; - -/** - * \brief Wraps a bNode in its Node instance. - * - * For all node-types a wrapper class is created. - * - * \note When adding a new node to blender, this method needs to be changed to return the correct - * Node instance. - * - * \see Node - */ -Node *COM_convert_bnode(bNode *b_node); - -/** - * \brief This function will add a date-type conversion rule when the to-socket does not support - * the from-socket actual data type. - */ -NodeOperation *COM_convert_data_type(const NodeOperationOutput &from, - const NodeOperationInput &to); - -/** - * \brief This function will add a resolution rule based on the settings of the NodeInput. - * - * \note Conversion logic is implemented in this function. - * \see InputSocketResizeMode for the possible conversions. - */ -void COM_convert_canvas(NodeOperationBuilder &builder, - NodeOperationOutput *from_socket, - NodeOperationInput *to_socket); - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc deleted file mode 100644 index c600be9d4af..00000000000 --- a/source/blender/compositor/intern/COM_Debug.cc +++ /dev/null @@ -1,413 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "COM_Debug.h" - -#include "BLI_assert.h" -#include "BLI_fileops.h" -#include "BLI_path_utils.hh" -#include "BLI_string.h" - -#include "BKE_appdir.hh" -#include "IMB_imbuf.hh" -#include "IMB_imbuf_types.hh" - -#include "COM_SetValueOperation.h" -#include "COM_ViewerOperation.h" - -namespace blender::compositor { - -int DebugInfo::file_index_ = 0; -DebugInfo::NodeNameMap DebugInfo::node_names_; -DebugInfo::OpNameMap DebugInfo::op_names_; -std::string DebugInfo::current_node_name_; -std::string DebugInfo::current_op_name_; - -static std::string operation_class_name(const NodeOperation *op) -{ - std::string full_name = typeid(*op).name(); - /* The typeid name is implementation defined, but it is typically a full C++ name that is either - * mangled or demangled. In case it was demangled, remove the namespaces, but if it was mangled, - * return the entire name, since there is no easy way to demangle it. */ - size_t pos = full_name.find_last_of(':'); - if (pos == std::string::npos) { - return full_name; - } - return full_name.substr(pos + 1); -} - -std::string DebugInfo::node_name(const Node *node) -{ - NodeNameMap::const_iterator it = node_names_.find(node); - if (it != node_names_.end()) { - return it->second; - } - return ""; -} - -std::string DebugInfo::operation_name(const NodeOperation *op) -{ - OpNameMap::const_iterator it = op_names_.find(op); - if (it != op_names_.end()) { - return it->second; - } - return ""; -} - -int DebugInfo::graphviz_operation(const ExecutionSystem *system, - NodeOperation *operation, - char *str, - int maxlen) -{ - int len = 0; - - std::string fillcolor = "gainsboro"; - if (operation->get_flags().is_viewer_operation) { - const ViewerOperation *viewer = (const ViewerOperation *)operation; - if (viewer->is_active_viewer_output()) { - fillcolor = "lightskyblue1"; - } - else { - fillcolor = "lightskyblue3"; - } - } - else if (operation->is_output_operation(system->get_context().is_rendering())) { - fillcolor = "dodgerblue1"; - } - else if (operation->get_flags().is_constant_operation) { - fillcolor = "khaki1"; - } - - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "// OPERATION: %p\r\n", operation); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\"O_%p\"", operation); - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - " [fillcolor=%s,style=filled,shape=record,label=\"{", - fillcolor.c_str()); - - int totinputs = operation->get_number_of_input_sockets(); - if (totinputs != 0) { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{"); - for (int k = 0; k < totinputs; k++) { - NodeOperationInput *socket = operation->get_input_socket(k); - if (k != 0) { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|"); - } - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "", socket); - switch (socket->get_data_type()) { - case DataType::Value: - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value"); - break; - case DataType::Vector: - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Vector"); - break; - case DataType::Color: - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Color"); - break; - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } - } - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|"); - } - - if (COM_GRAPHVIZ_SHOW_NODE_NAME) { - std::string op_node_name = operation->get_name(); - if (!op_node_name.empty()) { - len += snprintf( - str + len, maxlen > len ? maxlen - len : 0, "%s\\n", (op_node_name + " Node").c_str()); - } - } - - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "%s\\n", - operation_class_name(operation).c_str()); - - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "#%d (%i,%i) (%u,%u)", - operation->get_id(), - operation->get_canvas().xmin, - operation->get_canvas().ymin, - operation->get_width(), - operation->get_height()); - - int totoutputs = operation->get_number_of_output_sockets(); - if (totoutputs != 0) { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{"); - for (int k = 0; k < totoutputs; k++) { - NodeOperationOutput *socket = operation->get_output_socket(k); - if (k != 0) { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "|"); - } - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "", socket); - switch (socket->get_data_type()) { - case DataType::Value: { - ConstantOperation *constant = operation->get_flags().is_constant_operation ? - static_cast(operation) : - nullptr; - if (constant && constant->can_get_constant_elem()) { - const float value = *constant->get_constant_elem(); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value\\n%12.4g", value); - } - else { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Value"); - } - break; - } - case DataType::Vector: { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Vector"); - break; - } - case DataType::Color: { - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "Color"); - break; - } - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } - } - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}"); - } - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\"]"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n"); - - return len; -} - -int DebugInfo::graphviz_legend_color(const char *name, const char *color, char *str, int maxlen) -{ - int len = 0; - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "%s\r\n", - name, - color); - return len; -} - -int DebugInfo::graphviz_legend_line( - const char * /*name*/, const char * /*color*/, const char * /*style*/, char *str, int maxlen) -{ - /* XXX TODO */ - int len = 0; - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n"); - return len; -} - -int DebugInfo::graphviz_legend_group( - const char *name, const char *color, const char * /*style*/, char *str, int maxlen) -{ - int len = 0; - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "%s
\r\n", - name, - color); - return len; -} - -int DebugInfo::graphviz_legend(char *str, int maxlen) -{ - int len = 0; - - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "{\r\n"); - len += snprintf( - str + len, maxlen > len ? maxlen - len : 0, "Legend [shape=none, margin=0, label=<\r\n"); - - len += snprintf( - str + len, - maxlen > len ? maxlen - len : 0, - " \r\n"); - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "\r\n"); - - len += graphviz_legend_color( - "NodeOperation", "gainsboro", str + len, maxlen > len ? maxlen - len : 0); - len += graphviz_legend_color( - "Output", "dodgerblue1", str + len, maxlen > len ? maxlen - len : 0); - len += graphviz_legend_color( - "Viewer", "lightskyblue3", str + len, maxlen > len ? maxlen - len : 0); - len += graphviz_legend_color( - "Active Viewer", "lightskyblue1", str + len, maxlen > len ? maxlen - len : 0); - len += graphviz_legend_color( - "Input Value", "khaki1", str + len, maxlen > len ? maxlen - len : 0); - - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "
Legend
\r\n"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, ">];\r\n"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n"); - - return len; -} - -bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int maxlen) -{ - int len = 0; - - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "digraph compositorexecution {\r\n"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "ranksep=1.5\r\n"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "rankdir=LR\r\n"); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "splines=false\r\n"); - - std::map> op_groups; - - for (NodeOperation *operation : system->operations_) { - if (op_groups.find(operation) != op_groups.end()) { - continue; - } - - op_groups[operation].push_back(std::string("")); - - len += graphviz_operation(system, operation, str + len, maxlen > len ? maxlen - len : 0); - } - - for (NodeOperation *op : system->operations_) { - for (NodeOperationInput &to : op->inputs_) { - NodeOperationOutput *from = to.get_link(); - - if (!from) { - continue; - } - - std::string color; - switch (from->get_data_type()) { - case DataType::Value: - color = "gray"; - break; - case DataType::Vector: - color = "blue"; - break; - case DataType::Color: - color = "orange"; - break; - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } - - NodeOperation *to_op = &to.get_operation(); - NodeOperation *from_op = &from->get_operation(); - std::vector &from_groups = op_groups[from_op]; - std::vector &to_groups = op_groups[to_op]; - - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - "// CONNECTION: %p.%p -> %p.%p\r\n", - from_op, - from, - to_op, - &to); - for (int k = 0; k < from_groups.size(); k++) { - for (int l = 0; l < to_groups.size(); l++) { - len += snprintf(str + len, - maxlen > len ? maxlen - len : 0, - R"("O_%p%s":"OUT_%p":e -> "O_%p%s":"IN_%p":w)", - from_op, - from_groups[k].c_str(), - from, - to_op, - to_groups[l].c_str(), - &to); - len += snprintf( - str + len, maxlen > len ? maxlen - len : 0, " [color=%s]", color.c_str()); - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "\r\n"); - } - } - } - } - - len += graphviz_legend(str + len, maxlen > len ? maxlen - len : 0); - - len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "}\r\n"); - - return (len < maxlen); -} - -void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name) -{ - if (!COM_EXPORT_GRAPHVIZ) { - return; - } - const int max_textlength = 1000000; - char *str = (char *)MEM_mallocN(max_textlength, __func__); - if (graphviz_system(system, str, max_textlength - 1)) { - char basename[FILE_MAX]; - char filepath[FILE_MAX]; - - if (name.is_empty()) { - SNPRINTF(basename, "compositor_%d.dot", file_index_); - } - else { - STRNCPY(basename, (name + ".dot").c_str()); - } - BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), basename); - file_index_++; - - std::cout << "Writing compositor debug to: " << filepath << "\n"; - - FILE *fp = BLI_fopen(filepath, "wb"); - fputs(str, fp); - fclose(fp); - } - MEM_freeN(str); -} - -static std::string get_operations_export_dir() -{ - return std::string(BKE_tempdir_session()) + "COM_operations" + SEP_STR; -} - -void DebugInfo::export_operation(const NodeOperation *op, MemoryBuffer *render) -{ - const int width = render->get_width(); - const int height = render->get_height(); - const int num_channels = render->get_num_channels(); - - ImBuf *ibuf = IMB_allocImBuf(width, height, 8 * num_channels, IB_rectfloat); - MemoryBuffer mem_ibuf(ibuf->float_buffer.data, 4, width, height); - mem_ibuf.copy_from(render, render->get_rect(), 0, num_channels, 0); - - const std::string file_name = operation_class_name(op) + "_" + std::to_string(op->get_id()) + - ".png"; - const std::string filepath = get_operations_export_dir() + file_name; - BLI_file_ensure_parent_dir_exists(filepath.c_str()); - IMB_saveiff(ibuf, filepath.c_str(), ibuf->flags); - IMB_freeImBuf(ibuf); -} - -void DebugInfo::delete_operation_exports() -{ - const std::string dir = get_operations_export_dir(); - if (BLI_exists(dir.c_str())) { - direntry *file_list; - int file_list_num = BLI_filelist_dir_contents(dir.c_str(), &file_list); - for (int i = 0; i < file_list_num; i++) { - direntry *file = &file_list[i]; - const eFileAttributes file_attrs = BLI_file_attributes(file->path); - if (file_attrs & FILE_ATTR_ANY_LINK) { - continue; - } - - if (BLI_is_file(file->path) && BLI_path_extension_check(file->path, ".png")) { - BLI_delete(file->path, false, false); - } - } - BLI_filelist_free(file_list, file_list_num); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h deleted file mode 100644 index 871ae393b08..00000000000 --- a/source/blender/compositor/intern/COM_Debug.h +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include -#include - -#include "BLI_vector.hh" - -#include "COM_ExecutionSystem.h" -#include "COM_MemoryBuffer.h" -#include "COM_Node.h" - -namespace blender::compositor { - -static constexpr bool COM_EXPORT_GRAPHVIZ = false; -static constexpr bool COM_GRAPHVIZ_SHOW_NODE_NAME = false; - -/* Saves operations results to image files. */ -static constexpr bool COM_EXPORT_OPERATION_BUFFERS = false; - -class Node; -class NodeOperation; -class ExecutionSystem; - -class DebugInfo { - public: - typedef std::map NodeNameMap; - typedef std::map OpNameMap; - - static std::string node_name(const Node *node); - static std::string operation_name(const NodeOperation *op); - - private: - static int file_index_; - /** Map nodes to usable names for debug output. */ - static NodeNameMap node_names_; - /** Map operations to usable names for debug output. */ - static OpNameMap op_names_; - /** Base name for all operations added by a node. */ - static std::string current_node_name_; - /** Base name for automatic sub-operations. */ - static std::string current_op_name_; - - public: - static void convert_started() - { - if (COM_EXPORT_GRAPHVIZ) { - op_names_.clear(); - } - } - - static void execute_started() - { - if (COM_EXPORT_GRAPHVIZ) { - file_index_ = 1; - } - if (COM_EXPORT_OPERATION_BUFFERS) { - delete_operation_exports(); - } - }; - - static void node_added(const Node *node) - { - if (COM_EXPORT_GRAPHVIZ) { - node_names_[node] = std::string(node->get_bnode() ? node->get_bnode()->name : ""); - } - } - - static void node_to_operations(const Node *node) - { - if (COM_EXPORT_GRAPHVIZ) { - current_node_name_ = node_names_[node]; - } - } - - static void operation_added(const NodeOperation *operation) - { - if (COM_EXPORT_GRAPHVIZ) { - op_names_[operation] = current_node_name_; - } - }; - - static void operation_read_write_buffer(const NodeOperation *operation) - { - if (COM_EXPORT_GRAPHVIZ) { - current_op_name_ = op_names_[operation]; - } - }; - - static void operation_rendered(const NodeOperation *op, MemoryBuffer *render) - { - /* Don't export constant operations as there are too many and it's rarely useful. */ - if (COM_EXPORT_OPERATION_BUFFERS && render && !render->is_a_single_elem()) { - export_operation(op, render); - } - } - - static void graphviz(const ExecutionSystem *system, StringRefNull name = ""); - - protected: - static int graphviz_operation(const ExecutionSystem *system, - NodeOperation *operation, - char *str, - int maxlen); - static int graphviz_legend_color(const char *name, const char *color, char *str, int maxlen); - static int graphviz_legend_line( - const char *name, const char *color, const char *style, char *str, int maxlen); - static int graphviz_legend_group( - const char *name, const char *color, const char *style, char *str, int maxlen); - static int graphviz_legend(char *str, int maxlen); - static bool graphviz_system(const ExecutionSystem *system, char *str, int maxlen); - - static void export_operation(const NodeOperation *op, MemoryBuffer *render); - static void delete_operation_exports(); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Device.cc b/source/blender/compositor/intern/COM_Device.cc deleted file mode 100644 index 06530631242..00000000000 --- a/source/blender/compositor/intern/COM_Device.cc +++ /dev/null @@ -1,5 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_Device.h" diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h deleted file mode 100644 index 56670cd998c..00000000000 --- a/source/blender/compositor/intern/COM_Device.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -struct WorkPackage; - -/** - * \brief Abstract class for device implementations to be used by the Compositor. - * devices are queried, initialized and used by the WorkScheduler. - * work are packaged as a WorkPackage instance. - */ -class Device { - - public: - Device() = default; - - Device(const Device &other) = delete; - Device(Device &&other) noexcept = default; - - Device &operator=(const Device &other) = delete; - Device &operator=(Device &&other) = delete; - - /** - * \brief Declaration of the virtual destructor - * \note resolve warning gcc 4.7 - */ - virtual ~Device() {} - - /** - * \brief execute a WorkPackage - * \param work: the WorkPackage to execute - */ - virtual void execute(struct WorkPackage *work) = 0; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:Device") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Enums.cc b/source/blender/compositor/intern/COM_Enums.cc deleted file mode 100644 index 04d3805da65..00000000000 --- a/source/blender/compositor/intern/COM_Enums.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_Enums.h" - -namespace blender::compositor { - -void expand_area_for_sampler(rcti &area, PixelSampler sampler) -{ - switch (sampler) { - case PixelSampler::Nearest: - break; - case PixelSampler::Bilinear: - area.xmax += 1; - area.ymax += 1; - break; - case PixelSampler::Bicubic: - area.xmin -= 1; - area.xmax += 2; - area.ymin -= 1; - area.ymax += 2; - break; - } -} - -std::ostream &operator<<(std::ostream &os, const eCompositorPriority &priority) -{ - switch (priority) { - case eCompositorPriority::High: { - os << "Priority::High"; - break; - } - case eCompositorPriority::Medium: { - os << "Priority::Medium"; - break; - } - case eCompositorPriority::Low: { - os << "Priority::Low"; - break; - } - } - return os; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Enums.h b/source/blender/compositor/intern/COM_Enums.h deleted file mode 100644 index a35e49541b4..00000000000 --- a/source/blender/compositor/intern/COM_Enums.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_defines.h" - -#include - -struct rcti; - -namespace blender::compositor { - -/** - * \brief Possible quality settings - * \see CompositorContext.quality - * \ingroup Execution - */ -enum class eCompositorQuality { - /** \brief High quality setting */ - High = 0, - /** \brief Medium quality setting */ - Medium = 1, - /** \brief Low quality setting */ - Low = 2, -}; - -/** - * \brief Possible priority settings - * \ingroup Execution - */ -enum class eCompositorPriority { - High = 2, - Medium = 1, - Low = 0, -}; - -enum class PixelSampler { - Nearest = 0, - Bilinear = 1, - Bicubic = 2, -}; -void expand_area_for_sampler(rcti &area, PixelSampler sampler); - -std::ostream &operator<<(std::ostream &os, const eCompositorPriority &priority); - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionModel.cc b/source/blender/compositor/intern/COM_ExecutionModel.cc deleted file mode 100644 index 0cb7890eb77..00000000000 --- a/source/blender/compositor/intern/COM_ExecutionModel.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ExecutionModel.h" -#include "COM_CompositorContext.h" - -namespace blender::compositor { - -ExecutionModel::ExecutionModel(CompositorContext &context, Span operations) - : context_(context), operations_(operations) -{ - const bNodeTree *node_tree = context_.get_bnodetree(); - - const rctf *viewer_border = &node_tree->viewer_border; - border_.use_viewer_border = (node_tree->flag & NTREE_VIEWER_BORDER) && - viewer_border->xmin < viewer_border->xmax && - viewer_border->ymin < viewer_border->ymax; - border_.viewer_border = viewer_border; - - const RenderData *rd = context_.get_render_data(); - /* Case when cropping to render border happens is handled in - * compositor output and render layer nodes. */ - border_.use_render_border = context.is_rendering() && (rd->mode & R_BORDER) && - !(rd->mode & R_CROP); - border_.render_border = &rd->border; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionModel.h b/source/blender/compositor/intern/COM_ExecutionModel.h deleted file mode 100644 index 5d1a1586b95..00000000000 --- a/source/blender/compositor/intern/COM_ExecutionModel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_span.hh" - -#include "DNA_vec_types.h" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -class CompositorContext; -class ExecutionSystem; -class NodeOperation; -class ProfilerData; - -/** - * Base class for execution models. Contains shared implementation. - */ -class ExecutionModel { - protected: - /** - * Render and viewer border info. Coordinates are normalized. - */ - struct { - bool use_render_border; - const rctf *render_border; - bool use_viewer_border; - const rctf *viewer_border; - } border_; - - /** - * Context used during execution. - */ - CompositorContext &context_; - - /** - * All operations being executed. - */ - Span operations_; - - public: - ExecutionModel(CompositorContext &context, Span operations); - - virtual ~ExecutionModel() {} - - virtual void execute(ExecutionSystem &exec_system) = 0; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:BaseExecutionModel") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc deleted file mode 100644 index 54551f75274..00000000000 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ExecutionSystem.h" - -#include "COM_Debug.h" -#include "COM_FullFrameExecutionModel.h" -#include "COM_NodeOperation.h" -#include "COM_NodeOperationBuilder.h" -#include "COM_WorkPackage.h" -#include "COM_WorkScheduler.h" - -#include "COM_profiler.hh" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -ExecutionSystem::ExecutionSystem(RenderData *rd, - Scene *scene, - bNodeTree *editingtree, - bool rendering, - const char *view_name, - realtime_compositor::RenderContext *render_context, - realtime_compositor::Profiler *profiler) -{ - num_work_threads_ = WorkScheduler::get_num_cpu_threads(); - context_.set_render_context(render_context); - context_.set_profiler(profiler); - context_.set_view_name(view_name); - context_.set_scene(scene); - context_.set_bnodetree(editingtree); - context_.set_preview_hash(editingtree->previews); - context_.set_rendering(rendering); - - context_.set_render_data(rd); - - BLI_mutex_init(&work_mutex_); - BLI_condition_init(&work_finished_cond_); - - { - NodeOperationBuilder builder(&context_, editingtree, this); - builder.convert_to_operations(this); - } - - execution_model_ = new FullFrameExecutionModel(context_, active_buffers_, operations_); -} - -ExecutionSystem::~ExecutionSystem() -{ - BLI_condition_end(&work_finished_cond_); - BLI_mutex_end(&work_mutex_); - - delete execution_model_; - - for (NodeOperation *operation : operations_) { - delete operation; - } - operations_.clear(); -} - -void ExecutionSystem::set_operations(const Span operations) -{ - operations_ = operations; -} - -void ExecutionSystem::execute() -{ - DebugInfo::execute_started(); - for (NodeOperation *op : operations_) { - op->init_data(); - } - execution_model_->execute(*this); - if (context_.get_profiler()) { - context_.get_profiler()->finalize(*context_.get_bnodetree()); - } -} - -void ExecutionSystem::execute_work(const rcti &work_rect, - std::function work_func) -{ - if (is_breaked()) { - return; - } - - /* Split work vertically to maximize continuous memory. */ - const int work_height = BLI_rcti_size_y(&work_rect); - const int num_sub_works = std::min(num_work_threads_, work_height); - const int split_height = num_sub_works == 0 ? 0 : work_height / num_sub_works; - int remaining_height = work_height - split_height * num_sub_works; - - Vector sub_works(num_sub_works); - int sub_work_y = work_rect.ymin; - int num_sub_works_finished = 0; - for (int i = 0; i < num_sub_works; i++) { - int sub_work_height = split_height; - - /* Distribute remaining height between sub-works. */ - if (remaining_height > 0) { - sub_work_height++; - remaining_height--; - } - - WorkPackage &sub_work = sub_works[i]; - sub_work.execute_fn = [=, &work_func, &work_rect]() { - if (is_breaked()) { - return; - } - rcti split_rect; - BLI_rcti_init( - &split_rect, work_rect.xmin, work_rect.xmax, sub_work_y, sub_work_y + sub_work_height); - work_func(split_rect); - }; - sub_work.executed_fn = [&]() { - BLI_mutex_lock(&work_mutex_); - num_sub_works_finished++; - if (num_sub_works_finished == num_sub_works) { - BLI_condition_notify_one(&work_finished_cond_); - } - BLI_mutex_unlock(&work_mutex_); - }; - WorkScheduler::schedule(&sub_work); - sub_work_y += sub_work_height; - } - BLI_assert(sub_work_y == work_rect.ymax); - - WorkScheduler::finish(); - - /* Ensure all sub-works finished. - * TODO: This a workaround for WorkScheduler::finish() not waiting all works on queue threading - * model. Sync code should be removed once it's fixed. */ - BLI_mutex_lock(&work_mutex_); - if (num_sub_works_finished < num_sub_works) { - BLI_condition_wait(&work_finished_cond_, &work_mutex_); - } - BLI_mutex_unlock(&work_mutex_); -} - -bool ExecutionSystem::is_breaked() const -{ - const bNodeTree *btree = context_.get_bnodetree(); - return btree->runtime->test_break(btree->runtime->tbh); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h deleted file mode 100644 index 70d3451dd9e..00000000000 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ /dev/null @@ -1,198 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "atomic_ops.h" - -#include "BLI_index_range.hh" -#include "BLI_threads.h" -#include "BLI_vector.hh" - -#include "COM_CompositorContext.h" -#include "COM_SharedOperationBuffers.h" - -#include "DNA_color_types.h" -#include "DNA_node_types.h" -#include "DNA_scene_types.h" -#include "DNA_vec_types.h" - -namespace blender::realtime_compositor { -class RenderContext; -class Profiler; -} // namespace blender::realtime_compositor - -namespace blender::compositor { - -/** - * \page execution Execution model - * In order to get to an efficient model for execution, several steps are being done. these steps - * are explained below. - * - * \section EM_Step1 Step 1: translating blender node system to the new compositor system - * Blenders node structure is based on C structs (DNA). These structs are not efficient in the new - * architecture. We want to use classes in order to simplify the system. during this step the - * blender node_tree is evaluated and converted to a CPP node system. - * - * \see ExecutionSystem - * \see Converter.convert - * \see Node - * - * \section EM_Step2 Step2: translating nodes to operations - * Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's. - * The new system only supports a single level of node_tree. - * We will 'flatten' the system in a single level. - * \see GroupNode - * \see ExecutionSystemHelper.ungroup - * - * Every node has the ability to convert itself to operations. The node itself is responsible to - * create a correct NodeOperation setup based on its internal settings. Most Node only need to - * convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything, but replaces - * itself with a ConvertColorToBWOperation. More complex nodes can use different NodeOperation - * based on settings; like MixNode. based on the selected Mixtype a different operation will be - * used. for more information see the page about creating new Nodes. [@subpage newnode] - * - * \see ExecutionSystem.convert_to_operations - * \see Node.convert_to_operations - * \see NodeOperation base class for all operations in the system - * - * \section EM_Step3 Step3: add additional conversions to the operation system - * - Data type conversions: the system has 3 data types DataType::Value, DataType::Vector, - * DataType::Color. The user can connect a Value socket to a color socket. As values are ordered - * differently than colors a conversion happens. - * - * - Image size conversions: the system can automatically convert when resolutions do not match. - * An NodeInput has a resize mode. This can be any of the following settings. - * - [@ref InputSocketResizeMode.ResizeMode::Center]: - * The center of both images are aligned - * - [@ref InputSocketResizeMode.ResizeMode::FitWidth]: - * The width of both images are aligned - * - [@ref InputSocketResizeMode.ResizeMode::FitHeight]: - * The height of both images are aligned - * - [@ref InputSocketResizeMode.ResizeMode::FitAny]: - * The width, or the height of both images are aligned to make sure that it fits. - * - [@ref InputSocketResizeMode.ResizeMode::Stretch]: - * The width and the height of both images are aligned. - * - [@ref InputSocketResizeMode.ResizeMode::None]: - * Bottom left of the images are aligned. - * - * \see COM_convert_data_type Datatype conversions - * \see Converter.convert_resolution Image size conversions - */ - -/* Forward declarations. */ -class ExecutionModel; -class NodeOperation; - -/** - * \brief the ExecutionSystem contains the whole compositor tree. - */ -class ExecutionSystem { - private: - /** - * Contains operations active buffers data. Buffers will be disposed once reader operations are - * finished. - */ - SharedOperationBuffers active_buffers_; - - /** - * \brief the context used during execution - */ - CompositorContext context_; - - /** - * \brief vector of operations - */ - Vector operations_; - - /** - * Active execution model implementation. - */ - ExecutionModel *execution_model_; - - /** - * Number of cpu threads available for work execution. - */ - int num_work_threads_; - - ThreadMutex work_mutex_; - ThreadCondition work_finished_cond_; - - public: - /** - * \brief Create a new ExecutionSystem and initialize it with the - * editingtree. - * - * \param editingtree: [bNodeTree *] - * \param rendering: [true false] - */ - ExecutionSystem(RenderData *rd, - Scene *scene, - bNodeTree *editingtree, - bool rendering, - const char *view_name, - realtime_compositor::RenderContext *render_context, - realtime_compositor::Profiler *profiler); - - /** - * Destructor - */ - ~ExecutionSystem(); - - void set_operations(Span operations); - - /** - * \brief execute this system - * - initialize the NodeOperation's - * - schedule the outputs based on their priority - * - deinitialize the NodeOperation's - */ - void execute(); - - /** - * \brief get the reference to the compositor context - */ - const CompositorContext &get_context() const - { - return context_; - } - - /** - * Multi-threadedly execute given work function passing work_rect splits as argument. - */ - void execute_work(const rcti &work_rect, std::function work_func); - - /** - * Multi-threaded execution of given work function passing work_rect splits as argument. - * Once finished, caller thread will call reduce_func for each thread result. - */ - template - void execute_work(const rcti &work_rect, - std::function work_func, - TResult &join, - std::function reduce_func) - { - Array chunks(num_work_threads_); - int num_started = 0; - execute_work(work_rect, [&](const rcti &split_rect) { - const int current = atomic_fetch_and_add_int32(&num_started, 1); - chunks[current] = work_func(split_rect); - }); - for (const int i : IndexRange(num_started)) { - reduce_func(join, chunks[i]); - } - } - - bool is_breaked() const; - - private: - /* allow the DebugInfo class to look at internals */ - friend class DebugInfo; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionSystem") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc deleted file mode 100644 index 8882fe34afd..00000000000 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc +++ /dev/null @@ -1,302 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_FullFrameExecutionModel.h" - -#include "BLI_string.h" - -#include "BLT_translation.hh" - -#include "COM_Debug.h" -#include "COM_ViewerOperation.h" -#include "COM_WorkScheduler.h" - -#include "COM_profiler.hh" - -#include "BLI_timeit.hh" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -FullFrameExecutionModel::FullFrameExecutionModel(CompositorContext &context, - SharedOperationBuffers &shared_buffers, - Span operations) - : ExecutionModel(context, operations), - active_buffers_(shared_buffers), - num_operations_finished_(0) -{ - priorities_.append(eCompositorPriority::High); - priorities_.append(eCompositorPriority::Medium); - priorities_.append(eCompositorPriority::Low); -} - -void FullFrameExecutionModel::execute(ExecutionSystem &exec_system) -{ - const bNodeTree *node_tree = this->context_.get_bnodetree(); - node_tree->runtime->stats_draw(node_tree->runtime->sdh, - RPT_("Compositing | Initializing execution")); - - DebugInfo::graphviz(&exec_system, "compositor_prior_rendering"); - - determine_areas_to_render_and_reads(); - render_operations(); -} - -void FullFrameExecutionModel::determine_areas_to_render_and_reads() -{ - const bool is_rendering = context_.is_rendering(); - const bNodeTree *node_tree = context_.get_bnodetree(); - - rcti area; - for (eCompositorPriority priority : priorities_) { - for (NodeOperation *op : operations_) { - op->set_bnodetree(node_tree); - if (op->is_output_operation(is_rendering) && op->get_render_priority() == priority) { - get_output_render_area(op, area); - determine_areas_to_render(op, area); - determine_reads(op); - } - } - } -} - -Vector FullFrameExecutionModel::get_input_buffers(NodeOperation *op, - const int output_x, - const int output_y) -{ - const int num_inputs = op->get_number_of_input_sockets(); - Vector inputs_buffers(num_inputs); - for (int i = 0; i < num_inputs; i++) { - 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->get_buffer(), buf->get_num_channels(), rect, buf->is_a_single_elem()); - } - return inputs_buffers; -} - -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->get_width(), output_y, output_y + op->get_height()); - - const DataType data_type = op->get_output_socket(0)->get_data_type(); - const bool is_a_single_elem = op->get_flags().is_constant_operation; - return new MemoryBuffer(data_type, rect, is_a_single_elem); -} - -void FullFrameExecutionModel::render_operation(NodeOperation *op) -{ - /* Output has no offset for easier image algorithms implementation on operations. */ - constexpr int output_x = 0; - constexpr int output_y = 0; - - const timeit::TimePoint before_time = timeit::Clock::now(); - - const bool has_outputs = op->get_number_of_output_sockets() > 0; - MemoryBuffer *op_buf = has_outputs ? create_operation_buffer(op, output_x, output_y) : nullptr; - if (op->get_width() > 0 && op->get_height() > 0) { - Vector input_bufs = get_input_buffers(op, output_x, output_y); - const int op_offset_x = output_x - op->get_canvas().xmin; - const int op_offset_y = output_y - op->get_canvas().ymin; - Vector areas = active_buffers_.get_areas_to_render(op, op_offset_x, op_offset_y); - op->render(op_buf, areas, input_bufs); - DebugInfo::operation_rendered(op, op_buf); - - for (MemoryBuffer *buf : input_bufs) { - delete buf; - } - } - /* Even if operation has no resolution set the empty buffer. It will be clipped with a - * TranslateOperation from convert resolutions if linked to an operation with resolution. */ - active_buffers_.set_rendered_buffer(op, std::unique_ptr(op_buf)); - - operation_finished(op); - - /* The operation may not come from any node. For example, it may have been added to convert data - * type. Do not accumulate time from its execution. */ - const timeit::TimePoint after_time = timeit::Clock::now(); - const bNodeInstanceKey node_instance_key = op->get_node_instance_key(); - if (context_.get_profiler() && node_instance_key != bke::NODE_INSTANCE_KEY_NONE) { - context_.get_profiler()->set_node_evaluation_time(node_instance_key, after_time - before_time); - } -} - -void FullFrameExecutionModel::render_operations() -{ - const bool is_rendering = context_.is_rendering(); - - WorkScheduler::start(); - for (eCompositorPriority priority : priorities_) { - for (NodeOperation *op : operations_) { - const bool has_size = op->get_width() > 0 && op->get_height() > 0; - const bool is_priority_output = op->is_output_operation(is_rendering) && - op->get_render_priority() == priority; - if (is_priority_output && has_size) { - render_output_dependencies(op); - render_operation(op); - } - else if (is_priority_output && !has_size && op->is_active_viewer_output()) { - static_cast(op)->clear_display_buffer(); - } - } - } - WorkScheduler::stop(); -} - -/** - * Returns all dependencies from inputs to outputs. A dependency may be repeated when - * several operations depend on it. - */ -static Vector get_operation_dependencies(NodeOperation *operation) -{ - /* Get dependencies from outputs to inputs. */ - Vector dependencies; - Vector next_outputs; - next_outputs.append(operation); - while (next_outputs.size() > 0) { - Vector outputs(next_outputs); - next_outputs.clear(); - for (NodeOperation *output : outputs) { - for (int i = 0; i < output->get_number_of_input_sockets(); i++) { - next_outputs.append(output->get_input_operation(i)); - } - } - dependencies.extend(next_outputs); - } - - /* Reverse to get dependencies from inputs to outputs. */ - std::reverse(dependencies.begin(), dependencies.end()); - - return dependencies; -} - -void FullFrameExecutionModel::render_output_dependencies(NodeOperation *output_op) -{ - BLI_assert(output_op->is_output_operation(context_.is_rendering())); - Vector dependencies = get_operation_dependencies(output_op); - for (NodeOperation *op : dependencies) { - if (!active_buffers_.is_operation_rendered(op)) { - render_operation(op); - } - } -} - -void FullFrameExecutionModel::determine_areas_to_render(NodeOperation *output_op, - const rcti &output_area) -{ - BLI_assert(output_op->is_output_operation(context_.is_rendering())); - - Vector> stack; - stack.append({output_op, output_area}); - while (stack.size() > 0) { - std::pair pair = stack.pop_last(); - NodeOperation *operation = pair.first; - const rcti &render_area = pair.second; - if (BLI_rcti_is_empty(&render_area) || - active_buffers_.is_area_registered(operation, render_area)) - { - continue; - } - - active_buffers_.register_area(operation, render_area); - - const int num_inputs = operation->get_number_of_input_sockets(); - for (int i = 0; i < num_inputs; i++) { - NodeOperation *input_op = operation->get_input_operation(i); - rcti input_area; - operation->get_area_of_interest(input_op, render_area, input_area); - - /* Ensure area of interest is within operation bounds, cropping areas outside. */ - BLI_rcti_isect(&input_area, &input_op->get_canvas(), &input_area); - - stack.append({input_op, input_area}); - } - } -} - -void FullFrameExecutionModel::determine_reads(NodeOperation *output_op) -{ - BLI_assert(output_op->is_output_operation(context_.is_rendering())); - - Vector stack; - stack.append(output_op); - while (stack.size() > 0) { - NodeOperation *operation = stack.pop_last(); - const int num_inputs = operation->get_number_of_input_sockets(); - for (int i = 0; i < num_inputs; i++) { - NodeOperation *input_op = operation->get_input_operation(i); - if (!active_buffers_.has_registered_reads(input_op)) { - stack.append(input_op); - } - active_buffers_.register_read(input_op); - } - } -} - -void FullFrameExecutionModel::get_output_render_area(NodeOperation *output_op, rcti &r_area) -{ - BLI_assert(output_op->is_output_operation(context_.is_rendering())); - - /* By default return operation bounds (no border). */ - rcti canvas = output_op->get_canvas(); - r_area = canvas; - - const bool has_viewer_border = border_.use_viewer_border && - (output_op->get_flags().is_viewer_operation || - output_op->get_flags().is_preview_operation); - const bool has_render_border = border_.use_render_border && - output_op->get_flags().use_render_border; - if (has_viewer_border || has_render_border) { - /* Get border with normalized coordinates. */ - const rctf *norm_border = has_viewer_border ? border_.viewer_border : border_.render_border; - - /* Return denormalized border within canvas. */ - const int w = output_op->get_width(); - const int h = output_op->get_height(); - r_area.xmin = canvas.xmin + norm_border->xmin * w; - r_area.xmax = canvas.xmin + norm_border->xmax * w; - r_area.ymin = canvas.ymin + norm_border->ymin * h; - r_area.ymax = canvas.ymin + norm_border->ymax * h; - } -} - -void FullFrameExecutionModel::operation_finished(NodeOperation *operation) -{ - /* Report inputs reads so that buffers may be freed/reused. */ - const int num_inputs = operation->get_number_of_input_sockets(); - for (int i = 0; i < num_inputs; i++) { - active_buffers_.read_finished(operation->get_input_operation(i)); - } - - num_operations_finished_++; - update_progress_bar(); -} - -void FullFrameExecutionModel::update_progress_bar() -{ - const bNodeTree *tree = context_.get_bnodetree(); - if (tree) { - const float progress = num_operations_finished_ / float(operations_.size()); - tree->runtime->progress(tree->runtime->prh, progress); - - char buf[128]; - SNPRINTF(buf, - RPT_("Compositing | Operation %i-%li"), - num_operations_finished_ + 1, - operations_.size()); - tree->runtime->stats_draw(tree->runtime->sdh, buf); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h b/source/blender/compositor/intern/COM_FullFrameExecutionModel.h deleted file mode 100644 index 66bc28fd013..00000000000 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_vector.hh" - -#include "COM_Enums.h" -#include "COM_ExecutionModel.h" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -/* Forward declarations. */ -class CompositorContext; -class ExecutionSystem; -class MemoryBuffer; -class NodeOperation; -class SharedOperationBuffers; - -/** - * Fully renders operations in order from inputs to outputs. - */ -class FullFrameExecutionModel : public ExecutionModel { - private: - /** - * Contains operations active buffers data. - * Buffers will be disposed once reader operations are finished. - */ - SharedOperationBuffers &active_buffers_; - - /** - * Number of operations finished. - */ - int num_operations_finished_; - - /** - * Order of priorities for output operations execution. - */ - Vector priorities_; - - public: - FullFrameExecutionModel(CompositorContext &context, - SharedOperationBuffers &shared_buffers, - Span operations); - - void execute(ExecutionSystem &exec_system) override; - - private: - void determine_areas_to_render_and_reads(); - /** - * Render output operations in order of priority. - */ - void render_operations(); - void render_output_dependencies(NodeOperation *output_op); - /** - * Returns input buffers with an offset relative to given output coordinates. - * Returned memory buffers must be deleted. - */ - Vector get_input_buffers(NodeOperation *op, int output_x, int output_y); - MemoryBuffer *create_operation_buffer(NodeOperation *op, int output_x, int output_y); - void render_operation(NodeOperation *op); - - void operation_finished(NodeOperation *operation); - - /** - * Calculates given output operation area to be rendered taking into account viewer and render - * borders. - */ - void get_output_render_area(NodeOperation *output_op, rcti &r_area); - /** - * Determines all operations areas needed to render given output area. - */ - void determine_areas_to_render(NodeOperation *output_op, const rcti &output_area); - /** - * Determines reads to receive by operations in output operation tree (i.e: Number of dependent - * operations each operation has). - */ - void determine_reads(NodeOperation *output_op); - - void update_progress_bar(); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:FullFrameExecutionModel") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc deleted file mode 100644 index 076724edd5d..00000000000 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ /dev/null @@ -1,534 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MemoryBuffer.h" - -#include "IMB_colormanagement.hh" -#include "IMB_imbuf_types.hh" - -#define ASSERT_BUFFER_CONTAINS_AREA(buf, area) \ - BLI_assert(BLI_rcti_inside_rcti(&(buf)->get_rect(), &(area))) - -#define ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(buf, area, x, y) \ - BLI_assert((buf)->get_rect().xmin <= (x)); \ - BLI_assert((buf)->get_rect().ymin <= (y)); \ - BLI_assert((buf)->get_rect().xmax >= (x) + BLI_rcti_size_x(&(area))); \ - BLI_assert((buf)->get_rect().ymax >= (y) + BLI_rcti_size_y(&(area))) - -#define ASSERT_VALID_ELEM_SIZE(buf, channel_offset, elem_size) \ - BLI_assert((buf)->get_num_channels() >= (channel_offset) + (elem_size)) - -namespace blender::compositor { - -static rcti create_rect(const int width, const int height) -{ - rcti rect; - BLI_rcti_init(&rect, 0, width, 0, height); - return rect; -} - -MemoryBuffer::MemoryBuffer(DataType data_type, int width, int height) -{ - BLI_rcti_init(&rect_, 0, width, 0, height); - is_a_single_elem_ = false; - num_channels_ = COM_data_type_num_channels(data_type); - buffer_ = (float *)MEM_mallocN_aligned( - sizeof(float) * buffer_len() * num_channels_, 16, "COM_MemoryBuffer"); - owns_data_ = true; - datatype_ = data_type; - - set_strides(); -} - -MemoryBuffer::MemoryBuffer(DataType data_type, const rcti &rect, bool is_a_single_elem) -{ - rect_ = rect; - is_a_single_elem_ = is_a_single_elem; - num_channels_ = COM_data_type_num_channels(data_type); - buffer_ = (float *)MEM_mallocN_aligned( - sizeof(float) * buffer_len() * num_channels_, 16, "COM_MemoryBuffer"); - owns_data_ = true; - datatype_ = data_type; - - set_strides(); -} - -MemoryBuffer::MemoryBuffer( - float *buffer, int num_channels, int width, int height, bool is_a_single_elem) - : MemoryBuffer(buffer, num_channels, create_rect(width, height), is_a_single_elem) -{ -} - -MemoryBuffer::MemoryBuffer(float *buffer, - const int num_channels, - const rcti &rect, - const bool is_a_single_elem) -{ - rect_ = rect; - is_a_single_elem_ = is_a_single_elem; - num_channels_ = num_channels; - datatype_ = COM_num_channels_data_type(num_channels); - buffer_ = buffer; - owns_data_ = false; - - set_strides(); -} - -MemoryBuffer::MemoryBuffer(const MemoryBuffer &src) : MemoryBuffer(src.datatype_, src.rect_, false) -{ - /* src may be single elem buffer */ - fill_from(src); -} - -void MemoryBuffer::set_strides() -{ - if (is_a_single_elem_) { - this->elem_stride = 0; - this->row_stride = 0; - } - else { - this->elem_stride = num_channels_; - this->row_stride = get_width() * num_channels_; - } - to_positive_x_stride_ = rect_.xmin < 0 ? -rect_.xmin + 1 : (rect_.xmin == 0 ? 1 : 0); - to_positive_y_stride_ = rect_.ymin < 0 ? -rect_.ymin + 1 : (rect_.ymin == 0 ? 1 : 0); -} - -void MemoryBuffer::clear() -{ - memset(buffer_, 0, buffer_len() * num_channels_ * sizeof(float)); -} - -BuffersIterator MemoryBuffer::iterate_with(Span inputs) -{ - return iterate_with(inputs, rect_); -} - -BuffersIterator MemoryBuffer::iterate_with(Span inputs, const rcti &area) -{ - BuffersIteratorBuilder builder(buffer_, rect_, area, elem_stride); - for (MemoryBuffer *input : inputs) { - builder.add_input(input->get_buffer(), input->get_rect(), input->elem_stride); - } - return builder.build(); -} - -MemoryBuffer *MemoryBuffer::inflate() const -{ - BLI_assert(is_a_single_elem()); - MemoryBuffer *inflated = new MemoryBuffer(datatype_, rect_, false); - inflated->copy_from(this, rect_); - return inflated; -} - -float MemoryBuffer::get_max_value() const -{ - float result = buffer_[0]; - const int64_t size = this->buffer_len(); - int64_t i; - - const float *fp_src = buffer_; - - for (i = 0; i < size; i++, fp_src += num_channels_) { - float value = *fp_src; - if (value > result) { - result = value; - } - } - - return result; -} - -float MemoryBuffer::get_max_value(const rcti &rect) const -{ - rcti rect_clamp; - - /* first clamp the rect by the bounds or we get un-initialized values */ - BLI_rcti_isect(&rect, &rect_, &rect_clamp); - - if (!BLI_rcti_is_empty(&rect_clamp)) { - MemoryBuffer temp_buffer(datatype_, rect_clamp); - temp_buffer.fill_from(*this); - return temp_buffer.get_max_value(); - } - - BLI_assert(0); - return 0.0f; -} - -MemoryBuffer::~MemoryBuffer() -{ - if (buffer_ && owns_data_) { - MEM_freeN(buffer_); - buffer_ = nullptr; - } -} - -void MemoryBuffer::copy_from(const MemoryBuffer *src, const rcti &area) -{ - copy_from(src, area, area.xmin, area.ymin); -} - -void MemoryBuffer::copy_from(const MemoryBuffer *src, - const rcti &area, - const int to_x, - const int to_y) -{ - BLI_assert(this->get_num_channels() == src->get_num_channels()); - copy_from(src, area, 0, src->get_num_channels(), to_x, to_y, 0); -} - -void MemoryBuffer::copy_from(const MemoryBuffer *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int to_channel_offset) -{ - copy_from(src, area, channel_offset, elem_size, area.xmin, area.ymin, to_channel_offset); -} - -void MemoryBuffer::copy_from(const MemoryBuffer *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int to_x, - const int to_y, - const int to_channel_offset) -{ - if (this->is_a_single_elem()) { - copy_single_elem_from(src, channel_offset, elem_size, to_channel_offset); - } - else if (!src->is_a_single_elem() && elem_size == src->get_num_channels() && - elem_size == this->get_num_channels()) - { - BLI_assert(to_channel_offset == 0); - BLI_assert(channel_offset == 0); - copy_rows_from(src, area, to_x, to_y); - } - else { - copy_elems_from(src, area, channel_offset, elem_size, to_x, to_y, to_channel_offset); - } -} - -void MemoryBuffer::copy_from(const uchar *src, const rcti &area) -{ - const int elem_stride = this->get_num_channels(); - const int row_stride = elem_stride * get_width(); - copy_from(src, area, 0, this->get_num_channels(), elem_stride, row_stride, 0); -} - -void MemoryBuffer::copy_from(const uchar *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int elem_stride, - const int row_stride, - const int to_channel_offset) -{ - copy_from(src, - area, - channel_offset, - elem_size, - elem_stride, - row_stride, - area.xmin, - area.ymin, - to_channel_offset); -} - -void MemoryBuffer::copy_from(const uchar *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int elem_stride, - const int row_stride, - const int to_x, - const int to_y, - const int to_channel_offset) -{ - ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y); - ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size); - - const int width = BLI_rcti_size_x(&area); - const int height = BLI_rcti_size_y(&area); - const uchar *const src_start = src + area.ymin * row_stride + channel_offset; - for (int y = 0; y < height; y++) { - const uchar *from_elem = src_start + y * row_stride + area.xmin * elem_stride; - float *to_elem = &this->get_value(to_x, to_y + y, to_channel_offset); - const float *row_end = to_elem + width * this->elem_stride; - while (to_elem < row_end) { - for (int i = 0; i < elem_size; i++) { - to_elem[i] = float(from_elem[i]) * (1.0f / 255.0f); - } - to_elem += this->elem_stride; - from_elem += elem_stride; - } - } -} - -void MemoryBuffer::apply_processor(ColormanageProcessor &processor, const rcti area) -{ - const int width = BLI_rcti_size_x(&area); - const int height = BLI_rcti_size_y(&area); - float *out = get_elem(area.xmin, area.ymin); - /* If area allows continuous memory do conversion in one step. Otherwise per row. */ - if (get_width() == width) { - IMB_colormanagement_processor_apply(&processor, out, width, height, get_num_channels(), false); - } - else { - for (int y = 0; y < height; y++) { - IMB_colormanagement_processor_apply(&processor, out, width, 1, get_num_channels(), false); - out += row_stride; - } - } -} - -static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, ColorSpace *colorspace) -{ - const int width = BLI_rcti_size_x(&area); - const int height = BLI_rcti_size_y(&area); - float *out = buf->get_elem(area.xmin, area.ymin); - /* If area allows continuous memory do conversion in one step. Otherwise per row. */ - if (buf->get_width() == width) { - IMB_colormanagement_colorspace_to_scene_linear( - out, width, height, buf->get_num_channels(), colorspace, false); - } - else { - for (int y = 0; y < height; y++) { - IMB_colormanagement_colorspace_to_scene_linear( - out, width, 1, buf->get_num_channels(), colorspace, false); - out += buf->row_stride; - } - } -} - -static void premultiply_alpha(MemoryBuffer *buf, const rcti &area) -{ - for (int y = area.ymin; y < area.ymax; y++) { - for (int x = area.xmin; x < area.xmax; x++) { - straight_to_premul_v4(buf->get_elem(x, y)); - } - } -} - -void MemoryBuffer::copy_from(const ImBuf *src, - const rcti &area, - const bool ensure_premultiplied, - const bool ensure_linear_space) -{ - copy_from(src, area, 0, this->get_num_channels(), 0, ensure_premultiplied, ensure_linear_space); -} - -void MemoryBuffer::copy_from(const ImBuf *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int to_channel_offset, - const bool ensure_premultiplied, - const bool ensure_linear_space) -{ - copy_from(src, - area, - channel_offset, - elem_size, - area.xmin, - area.ymin, - to_channel_offset, - ensure_premultiplied, - ensure_linear_space); -} - -void MemoryBuffer::copy_from(const ImBuf *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int to_x, - const int to_y, - const int to_channel_offset, - const bool ensure_premultiplied, - const bool ensure_linear_space) -{ - if (src->float_buffer.data) { - const MemoryBuffer mem_buf(src->float_buffer.data, src->channels, src->x, src->y, false); - copy_from(&mem_buf, area, channel_offset, elem_size, to_x, to_y, to_channel_offset); - } - else if (src->byte_buffer.data) { - const uchar *uc_buf = src->byte_buffer.data; - const int elem_stride = src->channels; - const int row_stride = elem_stride * src->x; - copy_from(uc_buf, - area, - channel_offset, - elem_size, - elem_stride, - row_stride, - to_x, - to_y, - to_channel_offset); - if (ensure_linear_space) { - colorspace_to_scene_linear(this, area, src->byte_buffer.colorspace); - } - if (ensure_premultiplied) { - premultiply_alpha(this, area); - } - } - else { - /* Empty ImBuf source. Fill destination with empty values. */ - const float *zero_elem = new float[elem_size]{0}; - fill(area, to_channel_offset, zero_elem, elem_size); - delete[] zero_elem; - } -} - -void MemoryBuffer::fill(const rcti &area, const float *value) -{ - fill(area, 0, value, this->get_num_channels()); -} - -void MemoryBuffer::fill(const rcti &area, - const int channel_offset, - const float *value, - const int value_size) -{ - const MemoryBuffer single_elem(const_cast(value), value_size, this->get_rect(), true); - copy_from(&single_elem, area, 0, value_size, area.xmin, area.ymin, channel_offset); -} - -void MemoryBuffer::fill_from(const MemoryBuffer &src) -{ - rcti overlap; - overlap.xmin = std::max(rect_.xmin, src.rect_.xmin); - overlap.xmax = std::min(rect_.xmax, src.rect_.xmax); - overlap.ymin = std::max(rect_.ymin, src.rect_.ymin); - overlap.ymax = std::min(rect_.ymax, src.rect_.ymax); - copy_from(&src, overlap); -} - -void MemoryBuffer::write_pixel(int x, int y, const float color[4]) -{ - if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) { - const intptr_t offset = get_coords_offset(x, y); - memcpy(&buffer_[offset], color, sizeof(float) * num_channels_); - } -} - -void MemoryBuffer::add_pixel(int x, int y, const float color[4]) -{ - if (x >= rect_.xmin && x < rect_.xmax && y >= rect_.ymin && y < rect_.ymax) { - const intptr_t offset = get_coords_offset(x, y); - float *dst = &buffer_[offset]; - const float *src = color; - for (int i = 0; i < num_channels_; i++, dst++, src++) { - *dst += *src; - } - } -} - -static void read_ewa_elem_checked(void *userdata, int x, int y, float result[4]) -{ - const MemoryBuffer *buffer = static_cast(userdata); - buffer->read_elem_checked(x, y, result); -} - -static void read_ewa_elem_clamped(void *userdata, int x, int y, float result[4]) -{ - const MemoryBuffer *buffer = static_cast(userdata); - buffer->read_elem_clamped(x, y, result); -} - -void MemoryBuffer::read_elem_filtered( - const float x, const float y, float dx[2], float dy[2], bool extend_boundary, float *out) const -{ - BLI_assert(datatype_ == DataType::Color); - - const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}}; - - float inv_width = 1.0f / float(this->get_width()), inv_height = 1.0f / float(this->get_height()); - /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, - * but compositor uses pixel space. For now let's just divide the values and - * switch compositor to normalized space for EWA later. - */ - float uv_normal[2] = {get_relative_x(x) * inv_width, get_relative_y(y) * inv_height}; - float du_normal[2] = {deriv[0][0] * inv_width, deriv[0][1] * inv_height}; - float dv_normal[2] = {deriv[1][0] * inv_width, deriv[1][1] * inv_height}; - - BLI_ewa_filter(this->get_width(), - this->get_height(), - false, - true, - uv_normal, - du_normal, - dv_normal, - extend_boundary ? read_ewa_elem_clamped : read_ewa_elem_checked, - const_cast(this), - out); -} - -void MemoryBuffer::copy_single_elem_from(const MemoryBuffer *src, - const int channel_offset, - const int elem_size, - const int to_channel_offset) -{ - ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size); - ASSERT_VALID_ELEM_SIZE(src, channel_offset, elem_size); - BLI_assert(this->is_a_single_elem()); - - float *to_elem = &this->get_value( - this->get_rect().xmin, this->get_rect().ymin, to_channel_offset); - const float *from_elem = &src->get_value( - src->get_rect().xmin, src->get_rect().ymin, channel_offset); - const int elem_bytes = elem_size * sizeof(float); - memcpy(to_elem, from_elem, elem_bytes); -} - -void MemoryBuffer::copy_rows_from(const MemoryBuffer *src, - const rcti &area, - const int to_x, - const int to_y) -{ - ASSERT_BUFFER_CONTAINS_AREA(src, area); - ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y); - BLI_assert(this->get_num_channels() == src->get_num_channels()); - BLI_assert(!this->is_a_single_elem()); - BLI_assert(!src->is_a_single_elem()); - - const int width = BLI_rcti_size_x(&area); - const int height = BLI_rcti_size_y(&area); - const int row_bytes = this->get_num_channels() * width * sizeof(float); - for (int y = 0; y < height; y++) { - float *to_row = this->get_elem(to_x, to_y + y); - const float *from_row = src->get_elem(area.xmin, area.ymin + y); - memcpy(to_row, from_row, row_bytes); - } -} - -void MemoryBuffer::copy_elems_from(const MemoryBuffer *src, - const rcti &area, - const int channel_offset, - const int elem_size, - const int to_x, - const int to_y, - const int to_channel_offset) -{ - ASSERT_BUFFER_CONTAINS_AREA(src, area); - ASSERT_BUFFER_CONTAINS_AREA_AT_COORDS(this, area, to_x, to_y); - ASSERT_VALID_ELEM_SIZE(this, to_channel_offset, elem_size); - ASSERT_VALID_ELEM_SIZE(src, channel_offset, elem_size); - - const int width = BLI_rcti_size_x(&area); - const int height = BLI_rcti_size_y(&area); - const int elem_bytes = elem_size * sizeof(float); - for (int y = 0; y < height; y++) { - float *to_elem = &this->get_value(to_x, to_y + y, to_channel_offset); - const float *from_elem = &src->get_value(area.xmin, area.ymin + y, channel_offset); - const float *row_end = to_elem + width * this->elem_stride; - while (to_elem < row_end) { - memcpy(to_elem, from_elem, elem_bytes); - to_elem += this->elem_stride; - from_elem += src->elem_stride; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h deleted file mode 100644 index 80f22bdf529..00000000000 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ /dev/null @@ -1,691 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_BufferArea.h" -#include "COM_BufferRange.h" -#include "COM_BuffersIterator.h" -#include "COM_Enums.h" - -#include "BLI_math_base.hh" -#include "BLI_math_interp.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector_types.hh" -#include "BLI_rect.h" - -#include -#include - -struct ColormanageProcessor; -struct ImBuf; - -namespace blender::compositor { - -enum class MemoryBufferExtend { - Clip, - Extend, - Repeat, -}; - -/** - * \brief a MemoryBuffer contains access to the data - */ -class MemoryBuffer { - public: - /** - * Offset between elements. - * - * Should always be used for the x dimension when calculating buffer offsets. - * It will be 0 when is_a_single_elem=true. - * e.g: buffer_index = y * buffer.row_stride + x * buffer.elem_stride - */ - int elem_stride; - - /** - * Offset between rows. - * - * Should always be used for the y dimension when calculating buffer offsets. - * It will be 0 when is_a_single_elem=true. - * e.g: buffer_index = y * buffer.row_stride + x * buffer.elem_stride - */ - int row_stride; - - private: - /** - * \brief the type of buffer DataType::Value, DataType::Vector, DataType::Color - */ - DataType datatype_; - - /** - * \brief region of this buffer inside - */ - rcti rect_; - - /** - * \brief the actual float buffer/data - */ - float *buffer_; - - /** - * \brief the number of channels of a single value in the buffer. - * For value buffers this is 1, vector 3 and color 4 - */ - uint8_t num_channels_; - - /** - * Whether buffer is a single element in memory. - */ - bool is_a_single_elem_; - - /** - * Whether MemoryBuffer owns buffer data. - */ - bool owns_data_; - - /** Stride to make any x coordinate within buffer positive (non-zero). */ - int to_positive_x_stride_; - - /** Stride to make any y coordinate within buffer positive (non-zero). */ - int to_positive_y_stride_; - - public: - /** - * \brief construct new temporarily MemoryBuffer for a width and height. - */ - MemoryBuffer(DataType data_type, int width, int height); - - /** - * \brief construct new temporarily MemoryBuffer for an area - */ - MemoryBuffer(DataType data_type, const rcti &rect, bool is_a_single_elem = false); - - /** - * Construct MemoryBuffer from a float buffer. MemoryBuffer is not responsible for - * freeing it. - */ - MemoryBuffer( - float *buffer, int num_channels, int width, int height, bool is_a_single_elem = false); - - /** - * Construct MemoryBuffer from a float buffer area. MemoryBuffer is not responsible for - * freeing given buffer. - */ - MemoryBuffer(float *buffer, int num_channels, const rcti &rect, bool is_a_single_elem = false); - - /** - * Copy constructor - */ - MemoryBuffer(const MemoryBuffer &src); - - /** - * \brief destructor - */ - ~MemoryBuffer(); - - /** - * Whether buffer is a single element in memory independently of its resolution. True for set - * operations buffers. - */ - bool is_a_single_elem() const - { - return is_a_single_elem_; - } - - float &operator[](int index) - { - BLI_assert(is_a_single_elem_ ? index < num_channels_ : - index < get_coords_offset(get_width(), get_height())); - return buffer_[index]; - } - - const float &operator[](int index) const - { - BLI_assert(is_a_single_elem_ ? index < num_channels_ : - index < get_coords_offset(get_width(), get_height())); - return buffer_[index]; - } - - /** - * Get offset needed to jump from buffer start to given coordinates. - */ - intptr_t get_coords_offset(int x, int y) const - { - return ((intptr_t)y - rect_.ymin) * row_stride + ((intptr_t)x - rect_.xmin) * elem_stride; - } - - /** - * Get buffer element at given coordinates. - */ - float *get_elem(int x, int y) - { - BLI_assert(has_coords(x, y)); - return buffer_ + get_coords_offset(x, y); - } - - /** - * Get buffer element at given coordinates. - */ - const float *get_elem(int x, int y) const - { - BLI_assert(has_coords(x, y)); - return buffer_ + get_coords_offset(x, y); - } - - /** - * Get buffer element at given coordinates, clamped to border. - */ - const float *get_elem_clamped(int x, int y) const - { - const int clamped_x = math::clamp(x, 0, this->get_width() - 1); - const int clamped_y = math::clamp(y, 0, this->get_height() - 1); - return buffer_ + get_coords_offset(clamped_x, clamped_y); - } - - void read_elem(int x, int y, float *out) const - { - memcpy(out, get_elem(x, y), get_elem_bytes_len()); - } - - void read_elem_clamped(int x, int y, float *out) const - { - memcpy(out, get_elem_clamped(x, y), get_elem_bytes_len()); - } - - void read_elem_checked(int x, int y, float *out) const - { - if (!has_coords(x, y)) { - clear_elem(out); - } - else { - read_elem(x, y, out); - } - } - - void read_elem_checked(float x, float y, float *out) const - { - read_elem_checked(floor_x(x), floor_y(y), out); - } - - /* Equivalent to the GLSL texture() function with bilinear interpolation and extended boundary - * conditions. The coordinates are thus expected to have half-pixels offsets. A float4 is always - * returned regardless of the number of channels of the buffer, the remaining channels will be - * initialized with the template float4(0, 0, 0, 1). */ - float4 texture_bilinear_extend(float2 coordinates) const - { - if (is_a_single_elem_) { - float4 result = float4(0.0f, 0.0f, 0.0f, 1.0f); - memcpy(result, buffer_, get_elem_bytes_len()); - return result; - } - - const int2 size = int2(get_width(), get_height()); - const float2 texel_coordinates = (coordinates * float2(size)) - 0.5f; - - float4 result = float4(0.0f, 0.0f, 0.0f, 1.0f); - math::interpolate_bilinear_fl( - buffer_, result, size.x, size.y, num_channels_, texel_coordinates.x, texel_coordinates.y); - return result; - } - - /* Equivalent to the GLSL texture() function with nearest interpolation and extended boundary - * conditions. The coordinates are thus expected to have half-pixels offsets. A float4 is always - * returned regardless of the number of channels of the buffer, the remaining channels will be - * initialized with the template float4(0, 0, 0, 1). */ - float4 texture_nearest_extend(float2 coordinates) const - { - if (is_a_single_elem_) { - float4 result = float4(0.0f, 0.0f, 0.0f, 1.0f); - memcpy(result, buffer_, get_elem_bytes_len()); - return result; - } - - const int2 size = int2(get_width(), get_height()); - const float2 texel_coordinates = coordinates * float2(size); - - float4 result = float4(0.0f, 0.0f, 0.0f, 1.0f); - math::interpolate_nearest_fl( - buffer_, result, size.x, size.y, num_channels_, texel_coordinates.x, texel_coordinates.y); - return result; - } - - void read_elem_bilinear(float x, float y, float *out) const - { - read(out, x, y, PixelSampler::Bilinear); - } - - void read_elem_bicubic_bspline(float x, float y, float *out) const - { - if (is_a_single_elem_) { - memcpy(out, buffer_, get_elem_bytes_len()); - return; - } - - math::interpolate_cubic_bspline_fl(buffer_, - out, - this->get_width(), - this->get_height(), - num_channels_, - get_relative_x(x), - get_relative_y(y)); - } - - void read_elem_sampled(float x, float y, PixelSampler sampler, float *out) const - { - read(out, x, y, sampler); - } - - void read_elem_filtered( - float x, float y, float dx[2], float dy[2], bool extend_boundary, float *out) const; - - /** - * Get channel value at given coordinates. - */ - float &get_value(int x, int y, int channel) - { - BLI_assert(has_coords(x, y) && channel >= 0 && channel < num_channels_); - return buffer_[get_coords_offset(x, y) + channel]; - } - - /** - * Get channel value at given coordinates. - */ - const float &get_value(int x, int y, int channel) const - { - BLI_assert(has_coords(x, y) && channel >= 0 && channel < num_channels_); - return buffer_[get_coords_offset(x, y) + channel]; - } - - /** - * Get the buffer row end. - */ - const float *get_row_end(int y) const - { - BLI_assert(has_y(y)); - return buffer_ + (is_a_single_elem() ? num_channels_ : get_coords_offset(get_width(), y)); - } - - /** - * Get the number of elements in memory for a row. For single element buffers it will always - * be 1. - */ - int get_memory_width() const - { - return is_a_single_elem() ? 1 : get_width(); - } - - /** - * Get number of elements in memory for a column. For single element buffers it will - * always be 1. - */ - int get_memory_height() const - { - return is_a_single_elem() ? 1 : get_height(); - } - - uint8_t get_num_channels() const - { - return num_channels_; - } - - uint8_t get_elem_bytes_len() const - { - return num_channels_ * sizeof(float); - } - - /** - * Get all buffer elements as a range with no offsets. - */ - BufferRange as_range() - { - return BufferRange(buffer_, 0, buffer_len(), elem_stride); - } - - BufferRange as_range() const - { - return BufferRange(buffer_, 0, buffer_len(), elem_stride); - } - - BufferArea get_buffer_area(const rcti &area) - { - return BufferArea(buffer_, get_width(), area, elem_stride); - } - - BufferArea get_buffer_area(const rcti &area) const - { - return BufferArea(buffer_, get_width(), area, elem_stride); - } - - BuffersIterator iterate_with(Span inputs); - BuffersIterator iterate_with(Span inputs, const rcti &area); - - /** - * \brief get the data of this MemoryBuffer - * \note buffer should already be available in memory - */ - float *get_buffer() - { - return buffer_; - } - - /** - * Converts a single elem buffer to a full size buffer (allocates memory for all - * elements in resolution). - */ - MemoryBuffer *inflate() const; - - inline void wrap_pixel(float &x, - float &y, - MemoryBufferExtend extend_x, - MemoryBufferExtend extend_y) const - { - const float w = (float)get_width(); - const float h = (float)get_height(); - x = x - rect_.xmin; - y = y - rect_.ymin; - - switch (extend_x) { - case MemoryBufferExtend::Clip: - break; - case MemoryBufferExtend::Extend: - if (x < 0) { - x = 0.0f; - } - if (x >= w) { - x = w - 1; - } - break; - case MemoryBufferExtend::Repeat: - x = floored_fmod(x, w); - break; - } - - switch (extend_y) { - case MemoryBufferExtend::Clip: - break; - case MemoryBufferExtend::Extend: - if (y < 0) { - y = 0.0f; - } - if (y >= h) { - y = h - 1; - } - break; - case MemoryBufferExtend::Repeat: - y = floored_fmod(y, h); - break; - } - - x = x + rect_.xmin; - y = y + rect_.ymin; - } - - inline void read(float *result, - float x, - float y, - PixelSampler sampler = PixelSampler::Nearest, - MemoryBufferExtend extend_x = MemoryBufferExtend::Clip, - MemoryBufferExtend extend_y = MemoryBufferExtend::Clip) const - { - /* Extend is completely ignored for constants. This may need to be fixed in the future. */ - if (is_a_single_elem_) { - memcpy(result, buffer_, get_elem_bytes_len()); - return; - } - - this->wrap_pixel(x, y, extend_x, extend_y); - - if (sampler == PixelSampler::Nearest) { - read_elem_checked(int(floorf(x + 0.5f)), int(floorf(y + 0.5f)), result); - return; - } - - x = get_relative_x(x); - y = get_relative_y(y); - const float w = get_width(); - const float h = get_height(); - - /* Compute (linear interpolation) intersection with Clip. */ - float mult = 1.0f; - if (extend_x == MemoryBufferExtend::Clip) { - mult = std::min(x + 1.0f, w - x); - } - if (extend_y == MemoryBufferExtend::Clip) { - mult = std::min(mult, std::min(y + 1.0f, h - y)); - } - if (mult <= 0.0f) { - clear_elem(result); - return; - } - - if (sampler == PixelSampler::Bilinear) { - /* Sample using Extend or Repeat. */ - math::interpolate_bilinear_wrapmode_fl( - buffer_, - result, - w, - h, - num_channels_, - x, - y, - extend_x == MemoryBufferExtend::Repeat ? math::InterpWrapMode::Repeat : - math::InterpWrapMode::Extend, - extend_y == MemoryBufferExtend::Repeat ? math::InterpWrapMode::Repeat : - math::InterpWrapMode::Extend); - } - else { /* #PixelSampler::Bicubic */ - /* Sample using Extend (Repeat is not implemented by `interpolate_cubic_bspline`). */ - math::interpolate_cubic_bspline_fl(buffer_, result, w, h, num_channels_, x, y); - } - - /* Multiply by Clip intersection. */ - if (mult < 1.0f) { - for (int i = 0; i < num_channels_; ++i) { - result[i] *= mult; - } - } - } - void write_pixel(int x, int y, const float color[4]); - void add_pixel(int x, int y, const float color[4]); - inline void read_bilinear(float *result, - float x, - float y, - MemoryBufferExtend extend_x = MemoryBufferExtend::Clip, - MemoryBufferExtend extend_y = MemoryBufferExtend::Clip) const - { - float u = x; - float v = y; - this->wrap_pixel(u, v, extend_x, extend_y); - if ((extend_x != MemoryBufferExtend::Repeat && (u < 0.0f || u >= get_width())) || - (extend_y != MemoryBufferExtend::Repeat && (v < 0.0f || v >= get_height()))) - { - copy_vn_fl(result, num_channels_, 0.0f); - return; - } - if (is_a_single_elem_) { - memcpy(result, buffer_, sizeof(float) * num_channels_); - } - else { - math::interpolate_bilinear_wrapmode_fl( - buffer_, - result, - get_width(), - get_height(), - num_channels_, - u, - v, - extend_x == MemoryBufferExtend::Repeat ? math::InterpWrapMode::Repeat : - math::InterpWrapMode::Extend, - extend_y == MemoryBufferExtend::Repeat ? math::InterpWrapMode::Repeat : - math::InterpWrapMode::Extend); - } - } - - /** - * \brief Apply a color processor on the given area. - */ - void apply_processor(ColormanageProcessor &processor, const rcti area); - - void copy_from(const MemoryBuffer *src, const rcti &area); - void copy_from(const MemoryBuffer *src, const rcti &area, int to_x, int to_y); - void copy_from(const MemoryBuffer *src, - const rcti &area, - int channel_offset, - int elem_size, - int to_channel_offset); - void copy_from(const MemoryBuffer *src, - const rcti &area, - int channel_offset, - int elem_size, - int to_x, - int to_y, - int to_channel_offset); - void copy_from(const uchar *src, const rcti &area); - void copy_from(const uchar *src, - const rcti &area, - int channel_offset, - int elem_size, - int elem_stride, - int row_stride, - int to_channel_offset); - void copy_from(const uchar *src, - const rcti &area, - int channel_offset, - int elem_size, - int elem_stride, - int row_stride, - int to_x, - int to_y, - int to_channel_offset); - void copy_from(const struct ImBuf *src, - const rcti &area, - bool ensure_premultiplied = false, - bool ensure_linear_space = false); - void copy_from(const struct ImBuf *src, - const rcti &area, - int channel_offset, - int elem_size, - int to_channel_offset, - bool ensure_premultiplied = false, - bool ensure_linear_space = false); - void copy_from(const struct ImBuf *src, - const rcti &src_area, - int channel_offset, - int elem_size, - int to_x, - int to_y, - int to_channel_offset, - bool ensure_premultiplied = false, - bool ensure_linear_space = false); - - void fill(const rcti &area, const float *value); - void fill(const rcti &area, int channel_offset, const float *value, int value_size); - /** - * \brief add the content from other_buffer to this MemoryBuffer - * \param other_buffer: source buffer - * - * \note take care when running this on a new buffer since it won't fill in - * uninitialized values in areas where the buffers don't overlap. - */ - void fill_from(const MemoryBuffer &src); - - /** - * \brief get the rect of this MemoryBuffer - */ - const rcti &get_rect() const - { - return rect_; - } - - /** - * \brief get the width of this MemoryBuffer - */ - const int get_width() const - { - return BLI_rcti_size_x(&rect_); - } - - /** - * \brief get the height of this MemoryBuffer - */ - const int get_height() const - { - return BLI_rcti_size_y(&rect_); - } - - /** - * \brief clear the buffer. Make all pixels black transparent. - */ - void clear(); - - float get_max_value() const; - float get_max_value(const rcti &rect) const; - - private: - void set_strides(); - const int64_t buffer_len() const - { - return int64_t(get_memory_width()) * int64_t(get_memory_height()); - } - - void clear_elem(float *out) const - { - memset(out, 0, num_channels_ * sizeof(float)); - } - - template T get_relative_x(T x) const - { - return x - rect_.xmin; - } - - template T get_relative_y(T y) const - { - return y - rect_.ymin; - } - - template bool has_coords(T x, T y) const - { - return has_x(x) && has_y(y); - } - - template bool has_x(T x) const - { - return x >= rect_.xmin && x < rect_.xmax; - } - - template bool has_y(T y) const - { - return y >= rect_.ymin && y < rect_.ymax; - } - - /* Fast `floor(..)` functions. The caller should check result is within buffer bounds. - * It `ceil(..)` in near cases and when given coordinate - * is negative and less than buffer rect `min - 1`. */ - int floor_x(float x) const - { - return (int)(x + to_positive_x_stride_) - to_positive_x_stride_; - } - - int floor_y(float y) const - { - return (int)(y + to_positive_y_stride_) - to_positive_y_stride_; - } - - void copy_single_elem_from(const MemoryBuffer *src, - int channel_offset, - int elem_size, - int to_channel_offset); - void copy_rows_from(const MemoryBuffer *src, const rcti &src_area, int to_x, int to_y); - void copy_elems_from(const MemoryBuffer *src, - const rcti &area, - int channel_offset, - int elem_size, - int to_x, - int to_y, - int to_channel_offset); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MetaData.cc b/source/blender/compositor/intern/COM_MetaData.cc deleted file mode 100644 index 777ef72757c..00000000000 --- a/source/blender/compositor/intern/COM_MetaData.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MetaData.h" - -#include "BKE_image.hh" - -#include "RE_pipeline.h" - -namespace blender::compositor { - -void MetaData::add(const blender::StringRef key, const blender::StringRef value) -{ - entries_.add(key, value); -} - -bool MetaData::is_cryptomatte_layer() const -{ - return entries_.contains(META_DATA_KEY_CRYPTOMATTE_HASH) || - entries_.contains(META_DATA_KEY_CRYPTOMATTE_CONVERSION) || - entries_.contains(META_DATA_KEY_CRYPTOMATTE_MANIFEST); -} - -void MetaData::add_cryptomatte_entry(const blender::StringRef layer_name, - const blender::StringRefNull key, - const blender::StringRef value) -{ - add(blender::bke::cryptomatte::BKE_cryptomatte_meta_data_key(layer_name, key), value); -} - -void MetaData::replace_hash_neutral_cryptomatte_keys(const blender::StringRef layer_name) -{ - std::string cryptomatte_hash = entries_.pop_default(META_DATA_KEY_CRYPTOMATTE_HASH, ""); - std::string cryptomatte_conversion = entries_.pop_default(META_DATA_KEY_CRYPTOMATTE_CONVERSION, - ""); - std::string cryptomatte_manifest = entries_.pop_default(META_DATA_KEY_CRYPTOMATTE_MANIFEST, ""); - - if (cryptomatte_hash.length() || cryptomatte_conversion.length() || - cryptomatte_manifest.length()) - { - add_cryptomatte_entry(layer_name, "name", layer_name); - } - if (cryptomatte_hash.length()) { - add_cryptomatte_entry(layer_name, "hash", cryptomatte_hash); - } - if (cryptomatte_conversion.length()) { - add_cryptomatte_entry(layer_name, "conversion", cryptomatte_conversion); - } - if (cryptomatte_manifest.length()) { - add_cryptomatte_entry(layer_name, "manifest", cryptomatte_manifest); - } -} - -void MetaData::add_to_render_result(RenderResult *render_result) const -{ - for (MapItem entry : entries_.items()) { - BKE_render_result_stamp_data(render_result, entry.key.c_str(), entry.value.c_str()); - } -} - -void MetaData::for_each_entry( - FunctionRef callback) const -{ - for (MapItem entry : entries_.items()) { - callback(entry.key, entry.value); - } -} - -void MetaDataExtractCallbackData::add_meta_data(blender::StringRef key, - blender::StringRefNull value) -{ - if (!meta_data) { - meta_data = std::make_unique(); - } - meta_data->add(key, value); -} - -void MetaDataExtractCallbackData::set_cryptomatte_keys(blender::StringRef cryptomatte_layer_name) -{ - manifest_key = blender::bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, - "manifest"); - hash_key = blender::bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, - "hash"); - conversion_key = blender::bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name, - "conversion"); -} - -void MetaDataExtractCallbackData::extract_cryptomatte_meta_data(void *_data, - const char *propname, - char *propvalue, - int /*len*/) -{ - MetaDataExtractCallbackData *data = static_cast(_data); - blender::StringRefNull key(propname); - if (key == data->hash_key) { - data->add_meta_data(META_DATA_KEY_CRYPTOMATTE_HASH, propvalue); - } - else if (key == data->conversion_key) { - data->add_meta_data(META_DATA_KEY_CRYPTOMATTE_CONVERSION, propvalue); - } - else if (key == data->manifest_key) { - data->add_meta_data(META_DATA_KEY_CRYPTOMATTE_MANIFEST, propvalue); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MetaData.h b/source/blender/compositor/intern/COM_MetaData.h deleted file mode 100644 index bf7bb062db4..00000000000 --- a/source/blender/compositor/intern/COM_MetaData.h +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "BKE_cryptomatte.hh" -#include "BLI_function_ref.hh" -#include "BLI_map.hh" - -#include "MEM_guardedalloc.h" - -/* Forward declarations. */ -struct RenderResult; - -namespace blender::compositor { - -/* Cryptomatte includes hash in its meta data keys. The hash is generated from the render - * layer/pass name. Compositing happens without the knowledge of the original layer and pass. The - * next keys are used to transfer the cryptomatte meta data in a neutral way. The file output node - * will generate a hash based on the layer name configured by the user. - * - * The `{hash}` has no special meaning except to make sure that the meta data stays unique. */ -constexpr blender::StringRef META_DATA_KEY_CRYPTOMATTE_HASH("cryptomatte/{hash}/hash"); -constexpr blender::StringRef META_DATA_KEY_CRYPTOMATTE_CONVERSION("cryptomatte/{hash}/conversion"); -constexpr blender::StringRef META_DATA_KEY_CRYPTOMATTE_MANIFEST("cryptomatte/{hash}/manifest"); -constexpr blender::StringRef META_DATA_KEY_CRYPTOMATTE_NAME("cryptomatte/{hash}/name"); - -class MetaData { - private: - Map entries_; - void add_cryptomatte_entry(const blender::StringRef layer_name, - const blender::StringRefNull key, - const blender::StringRef value); - - public: - /* The pixels in the result represents data, which is not to be color-managed. */ - bool is_data = false; - /* The result stores a 4D vector as opposed to a 3D vector. This is the case for things like - * velocity passes, and we need to mark them as 4D in order to write them to file correctly. This - * field can be ignored for results that are not of type Vector. */ - bool is_4d_vector = false; - - void add(const blender::StringRef key, const blender::StringRef value); - - bool is_cryptomatte_layer() const; - - /** - * Replace the hash neutral cryptomatte keys with hashed versions. - * - * When a conversion happens it will also add the cryptomatte name key with the given - * `layer_name`. - */ - void replace_hash_neutral_cryptomatte_keys(const blender::StringRef layer_name); - void add_to_render_result(RenderResult *render_result) const; - - /* Invokes the given callback on each entry of the meta data. */ - void for_each_entry(FunctionRef callback) const; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:MetaData") -}; - -struct MetaDataExtractCallbackData { - std::unique_ptr meta_data; - std::string hash_key; - std::string conversion_key; - std::string manifest_key; - - void add_meta_data(blender::StringRef key, blender::StringRefNull value); - void set_cryptomatte_keys(blender::StringRef cryptomatte_layer_name); - /* C type callback function (StampCallback). */ - static void extract_cryptomatte_meta_data(void *_data, - const char *propname, - char *propvalue, - int /*len*/); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.cc b/source/blender/compositor/intern/COM_MultiThreadedOperation.cc deleted file mode 100644 index 695e83e8cf8..00000000000 --- a/source/blender/compositor/intern/COM_MultiThreadedOperation.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MultiThreadedOperation.h" -#include "COM_ExecutionSystem.h" - -namespace blender::compositor { - -MultiThreadedOperation::MultiThreadedOperation() -{ - num_passes_ = 1; - current_pass_ = 0; -} - -void MultiThreadedOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (current_pass_ = 0; current_pass_ < num_passes_; current_pass_++) { - update_memory_buffer_started(output, area, inputs); - exec_system_->execute_work(area, [=](const rcti &split_rect) { - update_memory_buffer_partial(output, split_rect, inputs); - }); - update_memory_buffer_finished(output, area, inputs); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.h b/source/blender/compositor/intern/COM_MultiThreadedOperation.h deleted file mode 100644 index f71d9193ee7..00000000000 --- a/source/blender/compositor/intern/COM_MultiThreadedOperation.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -class MultiThreadedOperation : public NodeOperation { - protected: - /** - * Number of execution passes. - */ - int num_passes_; - /** - * Current execution pass. - */ - int current_pass_; - - protected: - MultiThreadedOperation(); - - /** - * Called before an update memory buffer pass is executed. Single-threaded calls. - */ - virtual void update_memory_buffer_started(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) - { - } - - /** - * Executes operation updating a memory buffer area. Multi-threaded calls. - */ - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) = 0; - - /** - * Called after an update memory buffer pass is executed. Single-threaded calls. - */ - virtual void update_memory_buffer_finished(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) - { - } - - private: - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc deleted file mode 100644 index f395b63a8d9..00000000000 --- a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -MultiThreadedRowOperation::PixelCursor::PixelCursor(const int num_inputs) - : out(nullptr), out_stride(0), row_end(nullptr), ins(num_inputs), in_strides(num_inputs) -{ -} - -void MultiThreadedRowOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - BLI_assert(output != nullptr); - const int width = BLI_rcti_size_x(&area); - PixelCursor p(inputs.size()); - p.out_stride = output->elem_stride; - for (int i = 0; i < p.in_strides.size(); i++) { - p.in_strides[i] = inputs[i]->elem_stride; - } - - for (int y = area.ymin; y < area.ymax; y++) { - p.out = output->get_elem(area.xmin, y); - for (int i = 0; i < p.ins.size(); i++) { - p.ins[i] = inputs[i]->get_elem(area.xmin, y); - } - p.row_end = p.out + width * p.out_stride; - update_memory_buffer_row(p); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h b/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h deleted file mode 100644 index c88d231fa80..00000000000 --- a/source/blender/compositor/intern/COM_MultiThreadedRowOperation.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * Executes buffer updates per row. To be inherited only by operations with correlated coordinates - * between inputs and output. - */ -class MultiThreadedRowOperation : public MultiThreadedOperation { - protected: - struct PixelCursor { - float *out; - int out_stride; - const float *row_end; - Array ins; - Array in_strides; - - public: - PixelCursor(int num_inputs); - - void next() - { - BLI_assert(out < row_end); - out += out_stride; - for (int i = 0; i < ins.size(); i++) { - ins[i] += in_strides[i]; - } - } - }; - - protected: - virtual void update_memory_buffer_row(PixelCursor &p) = 0; - - private: - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) final; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Node.cc b/source/blender/compositor/intern/COM_Node.cc deleted file mode 100644 index ea7632fc6ad..00000000000 --- a/source/blender/compositor/intern/COM_Node.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BKE_node.hh" - -#include "RNA_access.hh" -#include "RNA_prototypes.hh" - -#include "COM_Node.h" /* own include */ - -namespace blender::compositor { - -/************** - **** Node **** - **************/ - -Node::Node(bNode *editor_node, bool create_sockets) - : editor_node_tree_(nullptr), - editor_node_(editor_node), - in_active_group_(false), - instance_key_(bke::NODE_INSTANCE_KEY_NONE) -{ - if (create_sockets) { - bNodeSocket *input = (bNodeSocket *)editor_node->inputs.first; - while (input != nullptr) { - DataType dt = DataType::Value; - if (input->type == SOCK_RGBA) { - dt = DataType::Color; - } - if (input->type == SOCK_VECTOR) { - dt = DataType::Vector; - } - - this->add_input_socket(dt, input); - input = input->next; - } - bNodeSocket *output = (bNodeSocket *)editor_node->outputs.first; - while (output != nullptr) { - DataType dt = DataType::Value; - if (output->type == SOCK_RGBA) { - dt = DataType::Color; - } - if (output->type == SOCK_VECTOR) { - dt = DataType::Vector; - } - - this->add_output_socket(dt, output); - output = output->next; - } - } -} - -Node::~Node() -{ - while (!outputs_.is_empty()) { - delete outputs_.pop_last(); - } - while (!inputs_.is_empty()) { - delete inputs_.pop_last(); - } -} - -void Node::add_input_socket(DataType datatype) -{ - this->add_input_socket(datatype, nullptr); -} - -void Node::add_input_socket(DataType datatype, bNodeSocket *bSocket) -{ - NodeInput *socket = new NodeInput(this, bSocket, datatype); - inputs_.append(socket); -} - -void Node::add_output_socket(DataType datatype) -{ - this->add_output_socket(datatype, nullptr); -} -void Node::add_output_socket(DataType datatype, bNodeSocket *bSocket) -{ - NodeOutput *socket = new NodeOutput(this, bSocket, datatype); - outputs_.append(socket); -} - -NodeOutput *Node::get_output_socket(uint index) const -{ - return outputs_[index]; -} - -NodeInput *Node::get_input_socket(uint index) const -{ - return inputs_[index]; -} - -bNodeSocket *Node::get_editor_input_socket(int editor_node_input_socket_index) -{ - bNodeSocket *bSock = (bNodeSocket *)this->get_bnode()->inputs.first; - int index = 0; - while (bSock != nullptr) { - if (index == editor_node_input_socket_index) { - return bSock; - } - index++; - bSock = bSock->next; - } - return nullptr; -} -bNodeSocket *Node::get_editor_output_socket(int editor_node_output_socket_index) -{ - bNodeSocket *bSock = (bNodeSocket *)this->get_bnode()->outputs.first; - int index = 0; - while (bSock != nullptr) { - if (index == editor_node_output_socket_index) { - return bSock; - } - index++; - bSock = bSock->next; - } - return nullptr; -} - -/******************* - **** NodeInput **** - *******************/ - -NodeInput::NodeInput(Node *node, bNodeSocket *b_socket, DataType datatype) - : node_(node), editor_socket_(b_socket), datatype_(datatype), link_(nullptr) -{ -} - -void NodeInput::set_link(NodeOutput *link) -{ - link_ = link; -} - -float NodeInput::get_editor_value_float() const -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get(&ptr, "default_value"); -} - -void NodeInput::get_editor_value_color(float *value) const -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get_array(&ptr, "default_value", value); -} - -void NodeInput::get_editor_value_vector(float *value) const -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get_array(&ptr, "default_value", value); -} - -/******************** - **** NodeOutput **** - ********************/ - -NodeOutput::NodeOutput(Node *node, bNodeSocket *b_socket, DataType datatype) - : node_(node), editor_socket_(b_socket), datatype_(datatype) -{ -} - -float NodeOutput::get_editor_value_float() -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get(&ptr, "default_value"); -} - -void NodeOutput::get_editor_value_color(float *value) -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get_array(&ptr, "default_value", value); -} - -void NodeOutput::get_editor_value_vector(float *value) -{ - PointerRNA ptr = RNA_pointer_create( - (ID *)get_node()->get_bnodetree(), &RNA_NodeSocket, get_bnode_socket()); - return RNA_float_get_array(&ptr, "default_value", value); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h deleted file mode 100644 index 7d79b342870..00000000000 --- a/source/blender/compositor/intern/COM_Node.h +++ /dev/null @@ -1,267 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_vector.hh" - -#include "DNA_node_types.h" - -/* common node includes - * added here so node files don't have to include themselves - */ -#include "COM_CompositorContext.h" -#include "COM_NodeConverter.h" - -namespace blender::compositor { - -class NodeOperation; -class NodeConverter; - -/** - * My node documentation. - */ -class Node { - private: - /** - * \brief stores the reference to the SDNA bNode struct - */ - bNodeTree *editor_node_tree_; - - /** - * \brief stores the reference to the SDNA bNode struct - */ - const bNode *editor_node_; - - /** - * \brief Is this node part of the active group - */ - bool in_active_group_; - - /** - * \brief Instance key to identify the node in an instance hash table - */ - bNodeInstanceKey instance_key_; - - protected: - /** - * \brief the list of actual input-sockets \see NodeInput - */ - Vector inputs_; - - /** - * \brief the list of actual output-sockets \see NodeOutput - */ - Vector outputs_; - - public: - Node(bNode *editor_node, bool create_sockets = true); - virtual ~Node(); - - /** - * \brief get the reference to the SDNA bNode struct - */ - const bNode *get_bnode() const - { - return editor_node_; - } - - /** - * \brief get the reference to the SDNA bNodeTree struct - */ - bNodeTree *get_bnodetree() const - { - return editor_node_tree_; - } - - /** - * \brief set the reference to the bNode - * \note used in Node instances to receive the storage/settings and complex - * node for highlight during execution. - * \param bNode: - */ - void set_bnode(bNode *node) - { - editor_node_ = node; - } - - /** - * \brief set the reference to the bNodeTree - * \param bNodeTree: - */ - void set_bnodetree(bNodeTree *nodetree) - { - editor_node_tree_ = nodetree; - } - - /** - * \brief get access to the vector of input sockets - */ - Span get_input_sockets() const - { - return inputs_; - } - - /** - * \brief get access to the vector of input sockets - */ - Span get_output_sockets() const - { - return outputs_; - } - - /** - * Get the reference to a certain output-socket. - * \param index: The index of the needed output-socket. - */ - NodeOutput *get_output_socket(unsigned int index = 0) const; - - /** - * get the reference to a certain input-socket. - * \param index: The index of the needed input-socket. - */ - NodeInput *get_input_socket(unsigned int index) const; - - /** - * \brief Is this node in the active group (the group that is being edited) - * \param is_in_active_group: - */ - void set_is_in_active_group(bool value) - { - in_active_group_ = value; - } - - /** - * \brief Is this node part of the active group - * the active group is the group that is currently being edited. When no group is edited, - * the active group will be the main tree (all nodes that are not part of a group will be active) - * \return bool [false:true] - */ - inline bool is_in_active_group() const - { - return in_active_group_; - } - - /** - * \brief convert node to operation - * - * \todo this must be described further - * - * \param system: the ExecutionSystem where the operations need to be added - * \param context: reference to the CompositorContext - */ - virtual void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const = 0; - - void set_instance_key(bNodeInstanceKey instance_key) - { - instance_key_ = instance_key; - } - bNodeInstanceKey get_instance_key() const - { - return instance_key_; - } - - protected: - /** - * \brief add an NodeInput to the collection of input-sockets - * \note may only be called in an constructor - * \param socket: the NodeInput to add - */ - void add_input_socket(DataType datatype); - void add_input_socket(DataType datatype, bNodeSocket *socket); - - /** - * \brief add an NodeOutput to the collection of output-sockets - * \note may only be called in an constructor - * \param socket: the NodeOutput to add - */ - void add_output_socket(DataType datatype); - void add_output_socket(DataType datatype, bNodeSocket *socket); - - bNodeSocket *get_editor_input_socket(int editor_node_input_socket_index); - bNodeSocket *get_editor_output_socket(int editor_node_output_socket_index); -}; - -/** - * \brief NodeInput are sockets that can receive data/input - * \ingroup Model - */ -class NodeInput { - private: - Node *node_; - bNodeSocket *editor_socket_; - - DataType datatype_; - - /** - * \brief link connected to this NodeInput. - * An input socket can only have a single link - */ - NodeOutput *link_; - - public: - NodeInput(Node *node, bNodeSocket *b_socket, DataType datatype); - - Node *get_node() const - { - return node_; - } - DataType get_data_type() const - { - return datatype_; - } - bNodeSocket *get_bnode_socket() const - { - return editor_socket_; - } - - void set_link(NodeOutput *link); - bool is_linked() const - { - return link_; - } - NodeOutput *get_link() - { - return link_; - } - - float get_editor_value_float() const; - void get_editor_value_color(float *value) const; - void get_editor_value_vector(float *value) const; -}; - -/** - * \brief NodeOutput are sockets that can send data/input - * \ingroup Model - */ -class NodeOutput { - private: - Node *node_; - bNodeSocket *editor_socket_; - - DataType datatype_; - - public: - NodeOutput(Node *node, bNodeSocket *b_socket, DataType datatype); - - Node *get_node() const - { - return node_; - } - DataType get_data_type() const - { - return datatype_; - } - bNodeSocket *get_bnode_socket() const - { - return editor_socket_; - } - - float get_editor_value_float(); - void get_editor_value_color(float *value); - void get_editor_value_vector(float *value); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeConverter.cc b/source/blender/compositor/intern/COM_NodeConverter.cc deleted file mode 100644 index b290b406740..00000000000 --- a/source/blender/compositor/intern/COM_NodeConverter.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_utildefines.h" - -#include "COM_Node.h" -#include "COM_NodeOperationBuilder.h" -#include "COM_SetColorOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" -#include "COM_SocketProxyOperation.h" - -#include "COM_NodeConverter.h" /* own include */ - -namespace blender::compositor { - -NodeConverter::NodeConverter(NodeOperationBuilder *builder) : builder_(builder) {} - -void NodeConverter::add_operation(NodeOperation *operation) -{ - builder_->add_operation(operation); -} - -void NodeConverter::map_input_socket(NodeInput *node_socket, NodeOperationInput *operation_socket) -{ - builder_->map_input_socket(node_socket, operation_socket); -} - -void NodeConverter::map_output_socket(NodeOutput *node_socket, - NodeOperationOutput *operation_socket) -{ - builder_->map_output_socket(node_socket, operation_socket); -} - -void NodeConverter::add_link(NodeOperationOutput *from, NodeOperationInput *to) -{ - builder_->add_link(from, to); -} - -void NodeConverter::add_preview(NodeOperationOutput *output) -{ - builder_->add_preview(output); -} - -void NodeConverter::add_node_input_preview(NodeInput *input) -{ - builder_->add_node_input_preview(input); -} - -NodeOperation *NodeConverter::set_invalid_output(NodeOutput *output) -{ - /* this is a really bad situation - bring on the pink! - so artists know this is bad */ - const float warning_color[4] = {1.0f, 0.0f, 1.0f, 1.0f}; - - SetColorOperation *operation = new SetColorOperation(); - operation->set_channels(warning_color); - - builder_->add_operation(operation); - builder_->map_output_socket(output, operation->get_output_socket()); - - return operation; -} - -NodeOperationOutput *NodeConverter::add_input_proxy(NodeInput *input, bool use_conversion) -{ - SocketProxyOperation *proxy = new SocketProxyOperation(input->get_data_type(), use_conversion); - builder_->add_operation(proxy); - - builder_->map_input_socket(input, proxy->get_input_socket(0)); - - return proxy->get_output_socket(); -} - -NodeOperationInput *NodeConverter::add_output_proxy(NodeOutput *output, bool use_conversion) -{ - SocketProxyOperation *proxy = new SocketProxyOperation(output->get_data_type(), use_conversion); - builder_->add_operation(proxy); - - builder_->map_output_socket(output, proxy->get_output_socket()); - - return proxy->get_input_socket(0); -} - -void NodeConverter::add_input_value(NodeOperationInput *input, float value) -{ - SetValueOperation *operation = new SetValueOperation(); - operation->set_value(value); - - builder_->add_operation(operation); - builder_->add_link(operation->get_output_socket(), input); -} - -void NodeConverter::add_input_color(NodeOperationInput *input, const float value[4]) -{ - SetColorOperation *operation = new SetColorOperation(); - operation->set_channels(value); - - builder_->add_operation(operation); - builder_->add_link(operation->get_output_socket(), input); -} - -void NodeConverter::add_input_vector(NodeOperationInput *input, const float value[3]) -{ - SetVectorOperation *operation = new SetVectorOperation(); - operation->set_vector(value); - - builder_->add_operation(operation); - builder_->add_link(operation->get_output_socket(), input); -} - -void NodeConverter::add_output_value(NodeOutput *output, float value) -{ - SetValueOperation *operation = new SetValueOperation(); - operation->set_value(value); - - builder_->add_operation(operation); - builder_->map_output_socket(output, operation->get_output_socket()); -} - -void NodeConverter::add_output_color(NodeOutput *output, const float value[4]) -{ - SetColorOperation *operation = new SetColorOperation(); - operation->set_channels(value); - - builder_->add_operation(operation); - builder_->map_output_socket(output, operation->get_output_socket()); -} - -void NodeConverter::add_output_vector(NodeOutput *output, const float value[3]) -{ - SetVectorOperation *operation = new SetVectorOperation(); - operation->set_vector(value); - - builder_->add_operation(operation); - builder_->map_output_socket(output, operation->get_output_socket()); -} - -void NodeConverter::register_viewer(ViewerOperation *viewer) -{ - builder_->register_viewer(viewer); -} - -ViewerOperation *NodeConverter::active_viewer() const -{ - return builder_->active_viewer(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeConverter.h b/source/blender/compositor/intern/COM_NodeConverter.h deleted file mode 100644 index 1f8da29ab61..00000000000 --- a/source/blender/compositor/intern/COM_NodeConverter.h +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -class NodeInput; -class NodeOutput; - -class NodeOperation; -class NodeOperationInput; -class NodeOperationOutput; -class NodeOperationBuilder; - -class ViewerOperation; - -/** - * Interface type for converting a \a Node into \a NodeOperation. - * This is passed to \a Node::convert_to_operation methods and allows them - * to register any number of operations, create links between them, - * and map original node sockets to their inputs or outputs. - */ -class NodeConverter { - public: - NodeConverter(NodeOperationBuilder *builder); - - /** - * Insert a new operation into the operations graph. - * The operation must be created by the node. - */ - void add_operation(NodeOperation *operation); - - /** - * Map input socket of the node to an operation socket. - * Links between nodes will then generate equivalent links between - * the mapped operation sockets. - * - * \note A \a Node input can be mapped to multiple \a NodeOperation inputs. - */ - void map_input_socket(NodeInput *node_socket, NodeOperationInput *operation_socket); - /** - * Map output socket of the node to an operation socket. - * Links between nodes will then generate equivalent links between - * the mapped operation sockets. - * - * \note A \a Node output can only be mapped to one \a NodeOperation output. - * Any existing operation output mapping will be replaced. - */ - void map_output_socket(NodeOutput *node_socket, NodeOperationOutput *operation_socket); - - /** - * Create a proxy operation for a node input. - * This operation will be removed later and replaced - * by direct links between the connected operations. - */ - NodeOperationOutput *add_input_proxy(NodeInput *input, bool use_conversion); - /** - * Create a proxy operation for a node output. - * This operation will be removed later and replaced - * by direct links between the connected operations. - */ - NodeOperationInput *add_output_proxy(NodeOutput *output, bool use_conversion); - - /** Define a constant input value. */ - void add_input_value(NodeOperationInput *input, float value); - /** Define a constant input color. */ - void add_input_color(NodeOperationInput *input, const float value[4]); - /** Define a constant input vector. */ - void add_input_vector(NodeOperationInput *input, const float value[3]); - - /** Define a constant output value. */ - void add_output_value(NodeOutput *output, float value); - /** Define a constant output color. */ - void add_output_color(NodeOutput *output, const float value[4]); - /** Define a constant output vector. */ - void add_output_vector(NodeOutput *output, const float value[3]); - - /** Add an explicit link between two operations. */ - void add_link(NodeOperationOutput *from, NodeOperationInput *to); - - /** Add a preview operation for a operation output. */ - void add_preview(NodeOperationOutput *output); - /** Add a preview operation for a node input. */ - void add_node_input_preview(NodeInput *input); - - /** - * When a node has no valid data - * \note missing image / group pointer, or missing render-layer from EXR. - */ - NodeOperation *set_invalid_output(NodeOutput *output); - - /** Define a viewer operation as the active output, if possible */ - void register_viewer(ViewerOperation *viewer); - /** The currently active viewer output operation */ - ViewerOperation *active_viewer() const; - - private: - /** The internal builder for storing the results of the graph construction. */ - NodeOperationBuilder *builder_; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompiler") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeGraph.cc b/source/blender/compositor/intern/COM_NodeGraph.cc deleted file mode 100644 index eb4c5c842a0..00000000000 --- a/source/blender/compositor/intern/COM_NodeGraph.cc +++ /dev/null @@ -1,292 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "DNA_node_types.h" - -#include "BKE_node.hh" -#include "BKE_node_runtime.hh" - -#include "COM_Converter.h" -#include "COM_Debug.h" -#include "COM_SocketProxyNode.h" - -#include "COM_NodeGraph.h" /* own include */ - -namespace blender::compositor { - -/******************* - **** NodeGraph **** - *******************/ - -NodeGraph::~NodeGraph() -{ - while (nodes_.size()) { - delete nodes_.pop_last(); - } -} - -void NodeGraph::from_bNodeTree(const CompositorContext &context, bNodeTree *tree) -{ - add_bNodeTree(context, 0, tree, bke::NODE_INSTANCE_KEY_BASE); -} - -bNodeSocket *NodeGraph::find_b_node_input(bNode *b_node, const char *identifier) -{ - for (bNodeSocket *b_sock = (bNodeSocket *)b_node->inputs.first; b_sock; b_sock = b_sock->next) { - if (STREQ(b_sock->identifier, identifier)) { - return b_sock; - } - } - return nullptr; -} - -bNodeSocket *NodeGraph::find_b_node_output(bNode *b_node, const char *identifier) -{ - for (bNodeSocket *b_sock = (bNodeSocket *)b_node->outputs.first; b_sock; b_sock = b_sock->next) { - if (STREQ(b_sock->identifier, identifier)) { - return b_sock; - } - } - return nullptr; -} - -void NodeGraph::add_node(Node *node, - bNodeTree *b_ntree, - bNodeInstanceKey key, - bool is_active_group) -{ - node->set_bnodetree(b_ntree); - node->set_instance_key(key); - node->set_is_in_active_group(is_active_group); - - nodes_.append(node); - - DebugInfo::node_added(node); -} - -void NodeGraph::add_link(NodeOutput *from_socket, NodeInput *to_socket) -{ - links_.append(Link(from_socket, to_socket)); - - /* register with the input */ - to_socket->set_link(from_socket); -} - -void NodeGraph::add_bNodeTree(const CompositorContext &context, - int nodes_start, - bNodeTree *tree, - bNodeInstanceKey parent_key) -{ - const bNodeTree *basetree = context.get_bnodetree(); - - /* Update viewers in the active edit-tree as well the base tree (for backdrop). */ - bool is_active_group = (parent_key.value == basetree->active_viewer_key.value); - - /* add all nodes of the tree to the node list */ - for (bNode *node = (bNode *)tree->nodes.first; node; node = node->next) { - bNodeInstanceKey key = bke::node_instance_key(parent_key, tree, node); - add_bNode(context, tree, node, key, is_active_group); - } - - NodeRange node_range(nodes_.begin() + nodes_start, nodes_.end()); - /* Add all node-links of the tree to the link list. */ - for (bNodeLink *nodelink = (bNodeLink *)tree->links.first; nodelink; nodelink = nodelink->next) { - add_bNodeLink(node_range, nodelink); - } -} - -void NodeGraph::add_bNode(const CompositorContext &context, - bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group) -{ - /* replace muted nodes by proxies for internal links */ - if (b_node->flag & NODE_MUTED) { - add_proxies_mute(b_ntree, b_node, key, is_active_group); - return; - } - - /* special node types */ - if (ELEM(b_node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) { - add_proxies_group(context, b_node, key); - } - else if (b_node->type == NODE_REROUTE) { - add_proxies_reroute(b_ntree, b_node, key, is_active_group); - } - else { - /* regular nodes, handled in Converter */ - Node *node = COM_convert_bnode(b_node); - if (node) { - add_node(node, b_ntree, key, is_active_group); - } - } -} - -NodeOutput *NodeGraph::find_output(const NodeRange &node_range, bNodeSocket *b_socket) -{ - for (Vector::iterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - for (NodeOutput *output : node->get_output_sockets()) { - if (output->get_bnode_socket() == b_socket) { - return output; - } - } - } - return nullptr; -} - -void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink) -{ - /** \note Ignore invalid links. */ - if (!(b_nodelink->flag & NODE_LINK_VALID)) { - return; - } - if ((b_nodelink->fromsock->flag & SOCK_UNAVAIL) || (b_nodelink->tosock->flag & SOCK_UNAVAIL) || - (b_nodelink->flag & NODE_LINK_MUTED)) - { - return; - } - - /* NOTE: a DNA input socket can have multiple NodeInput in the compositor tree! (proxies) - * The output then gets linked to each one of them. - */ - - NodeOutput *output = find_output(node_range, b_nodelink->fromsock); - if (!output) { - return; - } - - for (Vector::iterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - for (NodeInput *input : node->get_input_sockets()) { - if (input->get_bnode_socket() == b_nodelink->tosock && !input->is_linked()) { - add_link(output, input); - } - } - } -} - -/* **** Special proxy node type conversions **** */ - -void NodeGraph::add_proxies_mute(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group) -{ - for (const bNodeLink &b_link : b_node->internal_links()) { - SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link.fromsock, b_link.tosock, false); - add_node(proxy, b_ntree, key, is_active_group); - } -} - -void NodeGraph::add_proxies_skip(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group) -{ - for (bNodeSocket *output = (bNodeSocket *)b_node->outputs.first; output; output = output->next) { - bNodeSocket *input; - - /* look for first input with matching datatype for each output */ - for (input = (bNodeSocket *)b_node->inputs.first; input; input = input->next) { - if (input->type == output->type) { - break; - } - } - - if (input) { - SocketProxyNode *proxy = new SocketProxyNode(b_node, input, output, true); - add_node(proxy, b_ntree, key, is_active_group); - } - } -} - -void NodeGraph::add_proxies_group_inputs(bNode *b_node, bNode *b_node_io) -{ - bNodeTree *b_group_tree = (bNodeTree *)b_node->id; - BLI_assert(b_group_tree); /* should have been checked in advance */ - - /* not important for proxies */ - bNodeInstanceKey key = bke::NODE_INSTANCE_KEY_BASE; - bool is_active_group = false; - - for (bNodeSocket *b_sock_io = (bNodeSocket *)b_node_io->outputs.first; b_sock_io; - b_sock_io = b_sock_io->next) - { - bNodeSocket *b_sock_group = find_b_node_input(b_node, b_sock_io->identifier); - if (b_sock_group) { - SocketProxyNode *proxy = new SocketProxyNode(b_node_io, b_sock_group, b_sock_io, true); - add_node(proxy, b_group_tree, key, is_active_group); - } - } -} - -void NodeGraph::add_proxies_group_outputs(const CompositorContext & /*context*/, - bNode *b_node, - bNode *b_node_io) -{ - bNodeTree *b_group_tree = (bNodeTree *)b_node->id; - BLI_assert(b_group_tree); /* should have been checked in advance */ - - /* not important for proxies */ - bNodeInstanceKey key = bke::NODE_INSTANCE_KEY_BASE; - bool is_active_group = false; - - for (bNodeSocket *b_sock_io = (bNodeSocket *)b_node_io->inputs.first; b_sock_io; - b_sock_io = b_sock_io->next) - { - bNodeSocket *b_sock_group = find_b_node_output(b_node, b_sock_io->identifier); - if (b_sock_group) { - SocketProxyNode *proxy = new SocketProxyNode(b_node_io, b_sock_io, b_sock_group, true); - add_node(proxy, b_group_tree, key, is_active_group); - } - } -} - -void NodeGraph::add_proxies_group(const CompositorContext &context, - bNode *b_node, - bNodeInstanceKey key) -{ - bNodeTree *b_group_tree = (bNodeTree *)b_node->id; - - /* missing node group datablock can happen with library linking */ - if (!b_group_tree) { - /* This error case its handled in convert_to_operations() - * so we don't get un-converted sockets. */ - return; - } - - /* use node list size before adding proxies, so they can be connected in add_bNodeTree */ - int nodes_start = nodes_.size(); - - /* create proxy nodes for group input/output nodes */ - for (bNode *b_node_io = (bNode *)b_group_tree->nodes.first; b_node_io; - b_node_io = b_node_io->next) - { - if (b_node_io->type == NODE_GROUP_INPUT) { - add_proxies_group_inputs(b_node, b_node_io); - } - - if (b_node_io->type == NODE_GROUP_OUTPUT && (b_node_io->flag & NODE_DO_OUTPUT)) { - add_proxies_group_outputs(context, b_node, b_node_io); - } - } - - add_bNodeTree(context, nodes_start, b_group_tree, key); -} - -void NodeGraph::add_proxies_reroute(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group) -{ - SocketProxyNode *proxy = new SocketProxyNode( - b_node, (bNodeSocket *)b_node->inputs.first, (bNodeSocket *)b_node->outputs.first, false); - add_node(proxy, b_ntree, key, is_active_group); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeGraph.h b/source/blender/compositor/intern/COM_NodeGraph.h deleted file mode 100644 index a374c9ccc92..00000000000 --- a/source/blender/compositor/intern/COM_NodeGraph.h +++ /dev/null @@ -1,100 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "DNA_node_types.h" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -class CompositorContext; -class Node; -class NodeInput; -class NodeOutput; - -/** - * Internal representation of DNA node data. - * This structure is converted into operations by \a NodeCompiler. - */ -class NodeGraph { - public: - struct Link { - NodeOutput *from; - NodeInput *to; - - Link(NodeOutput *from, NodeInput *to) : from(from), to(to) {} - }; - - private: - Vector nodes_; - Vector links_; - - public: - ~NodeGraph(); - - Span nodes() const - { - return nodes_; - } - Span links() const - { - return links_; - } - - void from_bNodeTree(const CompositorContext &context, bNodeTree *tree); - - protected: - typedef std::pair::iterator, Vector::iterator> NodeRange; - - static bNodeSocket *find_b_node_input(bNode *b_node, const char *identifier); - static bNodeSocket *find_b_node_output(bNode *b_node, const char *identifier); - - void add_node(Node *node, bNodeTree *b_ntree, bNodeInstanceKey key, bool is_active_group); - void add_link(NodeOutput *from_socket, NodeInput *to_socket); - - void add_bNodeTree(const CompositorContext &context, - int nodes_start, - bNodeTree *tree, - bNodeInstanceKey parent_key); - - void add_bNode(const CompositorContext &context, - bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group); - - NodeOutput *find_output(const NodeRange &node_range, bNodeSocket *b_socket); - void add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink); - - /* **** Special proxy node type conversions **** */ - /* These nodes are not represented in the node graph themselves, - * but converted into a number of proxy links - */ - - void add_proxies_mute(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group); - void add_proxies_skip(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group); - - void add_proxies_group_inputs(bNode *b_node, bNode *b_node_io); - void add_proxies_group_outputs(const CompositorContext &context, - bNode *b_node, - bNode *b_node_io); - void add_proxies_group(const CompositorContext &context, bNode *b_node, bNodeInstanceKey key); - - void add_proxies_reroute(bNodeTree *b_ntree, - bNode *b_node, - bNodeInstanceKey key, - bool is_active_group); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeGraph") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc deleted file mode 100644 index e4c3354c425..00000000000 --- a/source/blender/compositor/intern/COM_NodeOperation.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "COM_ExecutionSystem.h" - -#include "COM_ConstantOperation.h" -#include "COM_NodeOperation.h" /* own include */ - -namespace blender::compositor { - -/******************* - **** NodeOperation **** - *******************/ - -NodeOperation::NodeOperation() -{ - canvas_input_index_ = 0; - canvas_ = COM_AREA_NONE; - btree_ = nullptr; -} - -float NodeOperation::get_constant_value_default(float default_value) -{ - BLI_assert(outputs_.size() > 0 && get_output_socket()->get_data_type() == DataType::Value); - return *get_constant_elem_default(&default_value); -} - -const float *NodeOperation::get_constant_elem_default(const float *default_elem) -{ - BLI_assert(outputs_.size() > 0); - if (get_flags().is_constant_operation) { - return static_cast(this)->get_constant_elem(); - } - - return default_elem; -} - -std::optional NodeOperation::generate_hash() -{ - params_hash_ = get_default_hash(canvas_.xmin, canvas_.xmax); - - /* Hash subclasses params. */ - is_hash_output_params_implemented_ = true; - hash_output_params(); - if (!is_hash_output_params_implemented_) { - return std::nullopt; - } - - hash_params(canvas_.ymin, canvas_.ymax); - if (outputs_.size() > 0) { - BLI_assert(outputs_.size() == 1); - hash_param(this->get_output_socket()->get_data_type()); - } - NodeOperationHash hash; - hash.params_hash_ = params_hash_; - - hash.parents_hash_ = 0; - for (NodeOperationInput &socket : inputs_) { - if (!socket.is_connected()) { - continue; - } - - NodeOperation &input = socket.get_link()->get_operation(); - const bool is_constant = input.get_flags().is_constant_operation; - combine_hashes(hash.parents_hash_, get_default_hash(is_constant)); - if (is_constant) { - const float *elem = ((ConstantOperation *)&input)->get_constant_elem(); - const int num_channels = COM_data_type_num_channels(socket.get_data_type()); - for (const int i : IndexRange(num_channels)) { - combine_hashes(hash.parents_hash_, get_default_hash(elem[i])); - } - } - else { - combine_hashes(hash.parents_hash_, get_default_hash(input.get_id())); - } - } - - hash.type_hash_ = typeid(*this).hash_code(); - hash.operation_ = this; - - return hash; -} - -NodeOperationOutput *NodeOperation::get_output_socket(uint index) -{ - return &outputs_[index]; -} - -NodeOperationInput *NodeOperation::get_input_socket(uint index) -{ - return &inputs_[index]; -} - -void NodeOperation::add_input_socket(DataType datatype, ResizeMode resize_mode) -{ - inputs_.append(NodeOperationInput(this, datatype, resize_mode)); -} - -void NodeOperation::add_output_socket(DataType datatype) -{ - outputs_.append(NodeOperationOutput(this, datatype)); -} - -void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - uint used_canvas_index = 0; - if (canvas_input_index_ == RESOLUTION_INPUT_ANY) { - for (NodeOperationInput &input : inputs_) { - rcti any_area = COM_AREA_NONE; - const bool determined = input.determine_canvas(preferred_area, any_area); - if (determined) { - r_area = any_area; - break; - } - used_canvas_index += 1; - } - } - else if (canvas_input_index_ < inputs_.size()) { - NodeOperationInput &input = inputs_[canvas_input_index_]; - input.determine_canvas(preferred_area, r_area); - used_canvas_index = canvas_input_index_; - } - - if (modify_determined_canvas_fn_) { - modify_determined_canvas_fn_(r_area); - } - - rcti unused_area = COM_AREA_NONE; - const rcti &local_preferred_area = r_area; - for (uint index = 0; index < inputs_.size(); index++) { - if (index == used_canvas_index) { - continue; - } - NodeOperationInput &input = inputs_[index]; - if (input.is_connected()) { - input.determine_canvas(local_preferred_area, unused_area); - } - } -} - -void NodeOperation::set_canvas_input_index(uint index) -{ - this->canvas_input_index_ = index; -} - -void NodeOperation::init_data() -{ - /* Pass. */ -} -void NodeOperation::init_execution() -{ - /* pass */ -} - -void NodeOperation::deinit_execution() -{ - /* pass */ -} - -void NodeOperation::set_canvas(const rcti &canvas_area) -{ - canvas_ = canvas_area; - flags_.is_canvas_set = true; -} - -const rcti &NodeOperation::get_canvas() const -{ - return canvas_; -} - -void NodeOperation::unset_canvas() -{ - BLI_assert(inputs_.is_empty()); - flags_.is_canvas_set = false; -} - -SocketReader *NodeOperation::get_input_socket_reader(uint index) -{ - return this->get_input_socket(index)->get_reader(); -} - -NodeOperation *NodeOperation::get_input_operation(int index) -{ - NodeOperationInput *input = get_input_socket(index); - if (input && input->is_connected()) { - return &input->get_link()->get_operation(); - } - - return nullptr; -} - -/* -------------------------------------------------------------------- */ -/** \name Full Frame Methods - * \{ */ - -void NodeOperation::get_area_of_interest(const int /*input_idx*/, - const rcti &output_area, - rcti &r_input_area) -{ - r_input_area = output_area; -} - -void NodeOperation::get_area_of_interest(NodeOperation *input_op, - const rcti &output_area, - rcti &r_input_area) -{ - for (int i = 0; i < get_number_of_input_sockets(); i++) { - if (input_op == get_input_operation(i)) { - get_area_of_interest(i, output_area, r_input_area); - return; - } - } - BLI_assert_msg(0, "input_op is not an input operation."); -} - -void NodeOperation::render(MemoryBuffer *output_buf, - Span areas, - Span inputs_bufs) -{ - render_full_frame(output_buf, areas, inputs_bufs); -} - -void NodeOperation::render_full_frame(MemoryBuffer *output_buf, - Span areas, - Span inputs_bufs) -{ - init_execution(); - for (const rcti &area : areas) { - update_memory_buffer(output_buf, area, inputs_bufs); - } - deinit_execution(); -} - -/** \} */ - -/***************** - **** OpInput **** - *****************/ - -NodeOperationInput::NodeOperationInput(NodeOperation *op, - DataType datatype, - ResizeMode resize_mode) - : operation_(op), datatype_(datatype), resize_mode_(resize_mode), link_(nullptr) -{ -} - -SocketReader *NodeOperationInput::get_reader() -{ - if (is_connected()) { - return &link_->get_operation(); - } - - return nullptr; -} - -bool NodeOperationInput::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - if (link_) { - link_->determine_canvas(preferred_area, r_area); - return !BLI_rcti_is_empty(&r_area); - } - return false; -} - -/****************** - **** OpOutput **** - ******************/ - -NodeOperationOutput::NodeOperationOutput(NodeOperation *op, DataType datatype) - : operation_(op), datatype_(datatype) -{ -} - -void NodeOperationOutput::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - NodeOperation &operation = get_operation(); - if (operation.get_flags().is_canvas_set) { - r_area = operation.get_canvas(); - } - else { - operation.determine_canvas(preferred_area, r_area); - if (!BLI_rcti_is_empty(&r_area)) { - operation.set_canvas(r_area); - } - } -} - -std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operation_flags) -{ - if (node_operation_flags.use_render_border) { - os << "render_border,"; - } - if (node_operation_flags.use_viewer_border) { - os << "view_border,"; - } - if (node_operation_flags.is_canvas_set) { - os << "canvas_set,"; - } - if (node_operation_flags.is_proxy_operation) { - os << "proxy,"; - } - if (node_operation_flags.is_viewer_operation) { - os << "viewer,"; - } - if (node_operation_flags.is_preview_operation) { - os << "preview,"; - } - if (!node_operation_flags.use_datatype_conversion) { - os << "no_conversion,"; - } - if (node_operation_flags.is_constant_operation) { - os << "contant_operation,"; - } - if (node_operation_flags.can_be_constant) { - os << "can_be_constant,"; - } - - return os; -} - -std::ostream &operator<<(std::ostream &os, const NodeOperation &node_operation) -{ - NodeOperationFlags flags = node_operation.get_flags(); - os << "NodeOperation("; - os << "id=" << node_operation.get_id(); - if (!node_operation.get_name().empty()) { - os << ",name=" << node_operation.get_name(); - } - os << ",flags={" << flags << "}"; - os << ")"; - - return os; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h deleted file mode 100644 index de755866187..00000000000 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ /dev/null @@ -1,570 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include -#include - -#include "BLI_ghash.h" -#include "BLI_hash.hh" -#include "BLI_math_base.hh" -#include "BLI_rect.h" -#include "BLI_span.hh" -#include "BLI_threads.h" -#include "BLI_utildefines.h" - -#include "COM_Enums.h" -#include "COM_MemoryBuffer.h" -#include "COM_MetaData.h" - -#include "BKE_node.hh" -#include "BKE_node_runtime.hh" - -#include "DNA_node_types.h" - -namespace blender::compositor { - -class ExecutionSystem; -class NodeOperation; -class NodeOperationOutput; - -typedef NodeOperation SocketReader; - -/** - * RESOLUTION_INPUT_ANY is a wildcard when any resolution of an input can be used. - * This solves the issue that the FileInputNode in a group node cannot find the - * correct resolution. - */ -static constexpr unsigned int RESOLUTION_INPUT_ANY = 999999; - -/** - * \brief Resize modes of inputsockets - * How are the input and working resolutions matched - * \ingroup Model - */ -enum class ResizeMode { - /** \brief Center the input image to the center of the working area of the node, no resizing - * occurs */ - Center = NS_CR_CENTER, - /** No resizing or translation. */ - None = NS_CR_NONE, - /** - * Input image is translated so that its bottom left matches the bottom left of the working area - * of the node, no resizing occurs. - */ - Align = 100, - /** \brief Fit the width of the input image to the width of the working area of the node */ - FitWidth = NS_CR_FIT_WIDTH, - /** \brief Fit the height of the input image to the height of the working area of the node */ - FitHeight = NS_CR_FIT_HEIGHT, - /** \brief Fit the width or the height of the input image to the width or height of the working - * area of the node, image will be larger than the working area */ - FitAny = NS_CR_FIT, - /** \brief Fit the width and the height of the input image to the width and height of the working - * area of the node, image will be equally larger than the working area */ - Stretch = NS_CR_STRETCH, -}; - -class NodeOperationInput { - private: - NodeOperation *operation_; - - /** - * Datatype of this socket. Is used for automatically data transformation. - * \section data-conversion - */ - DataType datatype_; - - /** Resize mode of this socket */ - ResizeMode resize_mode_; - - /** Connected output */ - NodeOperationOutput *link_; - - public: - NodeOperationInput(NodeOperation *op, - DataType datatype, - ResizeMode resize_mode = ResizeMode::Center); - - NodeOperation &get_operation() const - { - return *operation_; - } - DataType get_data_type() const - { - return datatype_; - } - - void set_link(NodeOperationOutput *link) - { - link_ = link; - } - NodeOperationOutput *get_link() const - { - return link_; - } - bool is_connected() const - { - return link_; - } - - void set_resize_mode(ResizeMode resize_mode) - { - resize_mode_ = resize_mode; - } - ResizeMode get_resize_mode() const - { - return resize_mode_; - } - - SocketReader *get_reader(); - - /** - * \return Whether canvas area could be determined. - */ - bool determine_canvas(const rcti &preferred_area, rcti &r_area); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation") -}; - -class NodeOperationOutput { - private: - NodeOperation *operation_; - - /** - * Datatype of this socket. Is used for automatically data transformation. - * \section data-conversion - */ - DataType datatype_; - - public: - NodeOperationOutput(NodeOperation *op, DataType datatype); - - NodeOperation &get_operation() const - { - return *operation_; - } - DataType get_data_type() const - { - return datatype_; - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation") -}; - -struct NodeOperationFlags { - /** - * Does the operation needs a viewer border. - * Basically, setting border need to happen for only operations - * which operates in render resolution buffers (like compositor - * output nodes). - * - * In this cases adding border will lead to mapping coordinates - * from output buffer space to input buffer spaces when executing - * operation. - * - * But nodes like viewer and file output just shall display or - * safe the same exact buffer which goes to their input, no need - * in any kind of coordinates mapping. - */ - bool use_render_border : 1; - bool use_viewer_border : 1; - - /** - * Is the canvas of the operation set. - */ - bool is_canvas_set : 1; - - bool is_proxy_operation : 1; - bool is_viewer_operation : 1; - bool is_preview_operation : 1; - - /** - * When set additional data conversion operations are added to - * convert the data. SocketProxyOperation don't always need to do data conversions. - * - * By default data conversions are enabled. - */ - bool use_datatype_conversion : 1; - - /** - * Whether operation is a primitive constant operation (Color/Vector/Value). - */ - bool is_constant_operation : 1; - - /** - * Whether operation have constant elements/pixels values when all its inputs are constant - * operations. - */ - bool can_be_constant : 1; - - NodeOperationFlags() - { - use_render_border = false; - use_viewer_border = false; - is_canvas_set = false; - is_proxy_operation = false; - is_viewer_operation = false; - is_preview_operation = false; - use_datatype_conversion = true; - is_constant_operation = false; - can_be_constant = false; - } -}; - -/** Hash that identifies an operation output result in the current execution. */ -struct NodeOperationHash { - private: - NodeOperation *operation_; - size_t type_hash_; - size_t parents_hash_; - size_t params_hash_; - - friend class NodeOperation; - - public: - NodeOperation *get_operation() const - { - return operation_; - } - - bool operator==(const NodeOperationHash &other) const - { - return type_hash_ == other.type_hash_ && parents_hash_ == other.parents_hash_ && - params_hash_ == other.params_hash_; - } - - bool operator!=(const NodeOperationHash &other) const - { - return !(*this == other); - } - - bool operator<(const NodeOperationHash &other) const - { - return type_hash_ < other.type_hash_ || - (type_hash_ == other.type_hash_ && parents_hash_ < other.parents_hash_) || - (type_hash_ == other.type_hash_ && parents_hash_ == other.parents_hash_ && - params_hash_ < other.params_hash_); - } -}; - -/** - * \brief NodeOperation contains calculation logic - * - * Subclasses needs to implement the execution method (defined in SocketReader) to implement logic. - * \ingroup Model - */ -class NodeOperation { - private: - int id_; - std::string name_; - bNodeInstanceKey node_instance_key_{bke::NODE_INSTANCE_KEY_NONE}; - - Vector inputs_; - Vector outputs_; - - size_t params_hash_; - bool is_hash_output_params_implemented_; - - /** - * \brief the index of the input socket that will be used to determine the canvas - */ - unsigned int canvas_input_index_; - - std::function modify_determined_canvas_fn_; - - /** - * \brief reference to the editing bNodeTree, used for break and update callback - */ - const bNodeTree *btree_; - - protected: - rcti canvas_ = COM_AREA_NONE; - - /** - * Flags how to evaluate this operation. - */ - NodeOperationFlags flags_; - - ExecutionSystem *exec_system_; - - public: - virtual ~NodeOperation() {} - - void set_name(const std::string name) - { - name_ = name; - } - - const std::string get_name() const - { - return name_; - } - - void set_id(const int id) - { - id_ = id; - } - - const int get_id() const - { - return id_; - } - - const void set_node_instance_key(const bNodeInstanceKey &node_instance_key) - { - node_instance_key_ = node_instance_key; - } - const bNodeInstanceKey get_node_instance_key() const - { - return node_instance_key_; - } - - /** Get constant value when operation is constant, otherwise return default_value. */ - float get_constant_value_default(float default_value); - /** Get constant elem when operation is constant, otherwise return default_elem. */ - const float *get_constant_elem_default(const float *default_elem); - - const NodeOperationFlags get_flags() const - { - return flags_; - } - - /** - * Generate a hash that identifies the operation result in the current execution. - * Requires `hash_output_params` to be implemented, otherwise `std::nullopt` is returned. - * If the operation parameters or its linked inputs change, the hash must be re-generated. - */ - std::optional generate_hash(); - - unsigned int get_number_of_input_sockets() const - { - return inputs_.size(); - } - unsigned int get_number_of_output_sockets() const - { - return outputs_.size(); - } - NodeOperationOutput *get_output_socket(unsigned int index = 0); - NodeOperationInput *get_input_socket(unsigned int index); - - NodeOperation *get_input_operation(int index); - - virtual void determine_canvas(const rcti &preferred_area, rcti &r_area); - - /** - * \brief is_output_operation determines whether this operation is an output of the - * ExecutionSystem during rendering or editing. - * - * Default behavior if not overridden, this operation will not be evaluated as being an output - * of the ExecutionSystem. - * - * \see ExecutionSystem - * \ingroup check - * \param rendering: [true false] - * true: rendering - * false: editing - * - * \return bool the result of this method - */ - virtual bool is_output_operation(bool /*rendering*/) const - { - return false; - } - - void set_bnodetree(const bNodeTree *tree) - { - btree_ = tree; - } - - void set_execution_system(ExecutionSystem *system) - { - exec_system_ = system; - } - - /** - * Initializes operation data needed after operations are linked and resolutions determined. For - * rendering heap memory data use init_execution(). - */ - virtual void init_data(); - - virtual void init_execution(); - - virtual void deinit_execution(); - - void set_canvas(const rcti &canvas_area); - const rcti &get_canvas() const; - /** - * Mainly used for re-determining canvas of constant operations in cases where preferred canvas - * depends on the constant element. - */ - void unset_canvas(); - - /** - * \brief is this operation the active viewer output - * user can select an ViewerNode to be active - * (the result of this node will be drawn on the backdrop). - * \return [true:false] - * \see BaseViewerOperation - */ - virtual bool is_active_viewer_output() const - { - return false; - } - - /** - * \brief set the index of the input socket that will determine the canvas of this - * operation \param index: the index to set - */ - void set_canvas_input_index(unsigned int index); - - /** - * Set a custom function to modify determined canvas from main input just before setting it - * as preferred for the other inputs. - */ - void set_determined_canvas_modifier(std::function fn) - { - modify_determined_canvas_fn_ = fn; - } - - /** - * \brief get the render priority of this node. - * \note only applicable for output operations like ViewerOperation - * \return eCompositorPriority - */ - virtual eCompositorPriority get_render_priority() const - { - return eCompositorPriority::Low; - } - - inline bool is_braked() const - { - return btree_->runtime->test_break(btree_->runtime->tbh); - } - - inline void update_draw() - { - if (btree_->runtime->update_draw) { - btree_->runtime->update_draw(btree_->runtime->udh); - } - } - - unsigned int get_width() const - { - return BLI_rcti_size_x(&get_canvas()); - } - - unsigned int get_height() const - { - return BLI_rcti_size_y(&get_canvas()); - } - - virtual MemoryBuffer *get_input_memory_buffer(MemoryBuffer ** /*memory_buffers*/) - { - return 0; - } - - /** - * Return the meta data associated with this branch. - * - * The return parameter holds an instance or is an nullptr. */ - virtual std::unique_ptr get_meta_data() - { - return std::unique_ptr(); - } - - /* -------------------------------------------------------------------- */ - /** \name Full Frame Methods - * \{ */ - - /** - * Executes operation image manipulation algorithm rendering given areas. - * \param output_buf: Buffer to write result to. - * \param areas: Areas within this operation bounds to render. - * \param inputs_bufs: Inputs operations buffers. - */ - void render(MemoryBuffer *output_buf, Span areas, Span inputs_bufs); - - /** - * Executes operation updating output memory buffer. Single-threaded calls. - */ - virtual void update_memory_buffer(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) - { - } - - /** - * \brief Get input operation area being read by this operation on rendering given output area. - * - * Implementation don't need to ensure r_input_area is within input operation bounds. - * The caller must clamp it. - * TODO: See if it's possible to use parameter overloading (input_id for example). - * - * \param input_idx: Input operation index for which we want to calculate the area being read. - * \param output_area: Area being rendered by this operation. - * \param r_input_area: Returned input operation area that needs to be read in order to render - * given output area. - */ - virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area); - void get_area_of_interest(NodeOperation *input_op, const rcti &output_area, rcti &r_input_area); - - /** \} */ - - protected: - NodeOperation(); - - /* Overridden by subclasses to allow merging equal operations on compiling. Implementations must - * hash any subclass parameter that affects the output result using `hash_params` methods. */ - virtual void hash_output_params() - { - is_hash_output_params_implemented_ = false; - } - - static void combine_hashes(size_t &combined, size_t other) - { - combined = BLI_ghashutil_combine_hash(combined, other); - } - - template void hash_param(T param) - { - combine_hashes(params_hash_, get_default_hash(param)); - } - - template void hash_params(T1 param1, T2 param2) - { - combine_hashes(params_hash_, get_default_hash(param1, param2)); - } - - template void hash_params(T1 param1, T2 param2, T3 param3) - { - combine_hashes(params_hash_, get_default_hash(param1, param2, param3)); - } - - void add_input_socket(DataType datatype, ResizeMode resize_mode = ResizeMode::Center); - void add_output_socket(DataType datatype); - - SocketReader *get_input_socket_reader(unsigned int index); - - private: - /** - * Renders given areas using operations full frame implementation. - */ - void render_full_frame(MemoryBuffer *output_buf, - Span areas, - Span inputs_bufs); - - /* allow the DebugInfo class to look at internals */ - friend class DebugInfo; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation") -}; - -std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operation_flags); -std::ostream &operator<<(std::ostream &os, const NodeOperation &node_operation); - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc deleted file mode 100644 index 91b1933f1ac..00000000000 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ /dev/null @@ -1,617 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "BLI_multi_value_map.hh" - -#include "BKE_node_runtime.hh" - -#include "COM_Converter.h" -#include "COM_Debug.h" - -#include "COM_PreviewOperation.h" -#include "COM_SetColorOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" -#include "COM_ViewerOperation.h" - -#include "COM_ConstantFolder.h" -#include "COM_NodeOperationBuilder.h" /* own include */ - -namespace blender::compositor { - -NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, - bNodeTree *b_nodetree, - ExecutionSystem *system) - : context_(context), exec_system_(system), current_node_(nullptr), active_viewer_(nullptr) -{ - graph_.from_bNodeTree(*context, b_nodetree); -} - -void NodeOperationBuilder::convert_to_operations(ExecutionSystem *system) -{ - /* interface handle for nodes */ - NodeConverter converter(this); - - for (Node *node : graph_.nodes()) { - current_node_ = node; - - DebugInfo::node_to_operations(node); - node->convert_to_operations(converter, *context_); - } - - current_node_ = nullptr; - - /* The input map constructed by nodes maps operation inputs to node inputs. - * Inverting yields a map of node inputs to all connected operation inputs, - * so multiple operations can use the same node input. - */ - blender::MultiValueMap inverse_input_map; - for (MutableMapItem item : input_map_.items()) { - inverse_input_map.add(item.value, item.key); - } - - for (const NodeGraph::Link &link : graph_.links()) { - NodeOutput *from = link.from; - NodeInput *to = link.to; - - NodeOperationOutput *op_from = output_map_.lookup_default(from, nullptr); - - const blender::Span op_to_list = inverse_input_map.lookup(to); - if (!op_from || op_to_list.is_empty()) { - /* XXX allow this? error/debug message? */ - // BLI_assert(false); - /* XXX NOTE: this can happen with certain nodes (e.g. OutputFile) - * which only generate operations in certain circumstances (rendering) - * just let this pass silently for now ... - */ - continue; - } - - for (NodeOperationInput *op_to : op_to_list) { - add_link(op_from, op_to); - } - } - - add_operation_input_constants(); - - resolve_proxies(); - - add_datatype_conversions(); - - save_graphviz("compositor_prior_folding"); - ConstantFolder folder(*this); - folder.fold_operations(); - - determine_canvases(); - - save_graphviz("compositor_prior_merging"); - merge_equal_operations(); - - /* links not available from here on */ - /* XXX make links_ a local variable to avoid confusion! */ - links_.clear(); - - prune_operations(); - - /* ensure topological (link-based) order of nodes */ - // sort_operations(); /* not needed yet. */ - - /* transfer resulting operations to the system */ - system->set_operations(operations_); -} - -void NodeOperationBuilder::add_operation(NodeOperation *operation) -{ - operation->set_id(operations_.size()); - operations_.append(operation); - if (current_node_) { - operation->set_name(current_node_->get_bnode()->name); - operation->set_node_instance_key(current_node_->get_instance_key()); - } - operation->set_execution_system(exec_system_); -} - -void NodeOperationBuilder::replace_operation_with_constant(NodeOperation *operation, - ConstantOperation *constant_operation) -{ - BLI_assert(constant_operation->get_number_of_input_sockets() == 0); - unlink_inputs_and_relink_outputs(operation, constant_operation); - add_operation(constant_operation); -} - -void NodeOperationBuilder::unlink_inputs_and_relink_outputs(NodeOperation *unlinked_op, - NodeOperation *linked_op) -{ - int i = 0; - while (i < links_.size()) { - Link &link = links_[i]; - if (&link.to()->get_operation() == unlinked_op) { - link.to()->set_link(nullptr); - links_.remove(i); - continue; - } - - if (&link.from()->get_operation() == unlinked_op) { - link.to()->set_link(linked_op->get_output_socket()); - links_[i] = Link(linked_op->get_output_socket(), link.to()); - } - i++; - } -} - -void NodeOperationBuilder::map_input_socket(NodeInput *node_socket, - NodeOperationInput *operation_socket) -{ - BLI_assert(current_node_); - BLI_assert(node_socket->get_node() == current_node_); - - /* NOTE: this maps operation sockets to node sockets. - * for resolving links the map will be inverted first in convert_to_operations, - * to get a list of links for each node input socket. - */ - input_map_.add_new(operation_socket, node_socket); -} - -void NodeOperationBuilder::map_output_socket(NodeOutput *node_socket, - NodeOperationOutput *operation_socket) -{ - BLI_assert(current_node_); - BLI_assert(node_socket->get_node() == current_node_); - - output_map_.add_new(node_socket, operation_socket); -} - -void NodeOperationBuilder::add_link(NodeOperationOutput *from, NodeOperationInput *to) -{ - if (to->is_connected()) { - return; - } - - links_.append(Link(from, to)); - - /* register with the input */ - to->set_link(from); -} - -void NodeOperationBuilder::remove_input_link(NodeOperationInput *to) -{ - int index = 0; - for (Link &link : links_) { - if (link.to() == to) { - /* unregister with the input */ - to->set_link(nullptr); - - links_.remove(index); - return; - } - index++; - } -} - -PreviewOperation *NodeOperationBuilder::make_preview_operation() const -{ - BLI_assert(current_node_); - - if (!(current_node_->get_bnode()->flag & NODE_PREVIEW)) { - return nullptr; - } - /* previews only in the active group */ - if (!current_node_->is_in_active_group()) { - return nullptr; - } - /* do not calculate previews of hidden nodes */ - if (current_node_->get_bnode()->flag & NODE_HIDDEN) { - return nullptr; - } - - bke::bNodeInstanceHash *previews = context_->get_preview_hash(); - if (previews) { - Scene *scene = context_->get_scene(); - PreviewOperation *operation = new PreviewOperation( - &scene->view_settings, - &scene->display_settings, - current_node_->get_bnode()->runtime->preview_xsize, - current_node_->get_bnode()->runtime->preview_ysize); - operation->set_bnodetree(context_->get_bnodetree()); - operation->verify_preview(previews, current_node_->get_instance_key()); - return operation; - } - - return nullptr; -} - -void NodeOperationBuilder::add_preview(NodeOperationOutput *output) -{ - PreviewOperation *operation = make_preview_operation(); - if (operation) { - add_operation(operation); - - add_link(output, operation->get_input_socket(0)); - } -} - -void NodeOperationBuilder::add_node_input_preview(NodeInput *input) -{ - PreviewOperation *operation = make_preview_operation(); - if (operation) { - add_operation(operation); - - map_input_socket(input, operation->get_input_socket(0)); - } -} - -void NodeOperationBuilder::register_viewer(ViewerOperation *viewer) -{ - if (!active_viewer_) { - active_viewer_ = viewer; - viewer->set_active(true); - return; - } - - /* A viewer is already registered, so we active this viewer but only if it is in the active node - * tree, since it takes precedence over viewer nodes in other trees. So deactivate existing - * viewer and set this viewer as active. */ - if (current_node_->is_in_active_group()) { - active_viewer_->set_active(false); - - active_viewer_ = viewer; - viewer->set_active(true); - } -} - -/**************************** - **** Optimization Steps **** - ****************************/ - -void NodeOperationBuilder::add_datatype_conversions() -{ - Vector convert_links; - for (const Link &link : links_) { - /* proxy operations can skip data type conversion */ - NodeOperation *from_op = &link.from()->get_operation(); - NodeOperation *to_op = &link.to()->get_operation(); - if (!(from_op->get_flags().use_datatype_conversion || - to_op->get_flags().use_datatype_conversion)) - { - continue; - } - - if (link.from()->get_data_type() != link.to()->get_data_type()) { - convert_links.append(link); - } - } - for (const Link &link : convert_links) { - NodeOperation *converter = COM_convert_data_type(*link.from(), *link.to()); - if (converter) { - add_operation(converter); - - remove_input_link(link.to()); - add_link(link.from(), converter->get_input_socket(0)); - add_link(converter->get_output_socket(0), link.to()); - } - } -} - -void NodeOperationBuilder::add_operation_input_constants() -{ - /* NOTE: unconnected inputs cached first to avoid modifying - * operations_ while iterating over it - */ - Vector pending_inputs; - for (NodeOperation *op : operations_) { - for (int k = 0; k < op->get_number_of_input_sockets(); ++k) { - NodeOperationInput *input = op->get_input_socket(k); - if (!input->is_connected()) { - pending_inputs.append(input); - } - } - } - for (NodeOperationInput *input : pending_inputs) { - add_input_constant_value(input, input_map_.lookup_default(input, nullptr)); - } -} - -void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, - const NodeInput *node_input) -{ - switch (input->get_data_type()) { - case DataType::Value: { - float value; - if (node_input && node_input->get_bnode_socket()) { - value = node_input->get_editor_value_float(); - } - else { - value = 0.0f; - } - - SetValueOperation *op = new SetValueOperation(); - op->set_value(value); - add_operation(op); - add_link(op->get_output_socket(), input); - break; - } - case DataType::Color: { - float value[4]; - if (node_input && node_input->get_bnode_socket()) { - node_input->get_editor_value_color(value); - } - else { - zero_v4(value); - } - - SetColorOperation *op = new SetColorOperation(); - op->set_channels(value); - add_operation(op); - add_link(op->get_output_socket(), input); - break; - } - case DataType::Vector: { - float value[3]; - if (node_input && node_input->get_bnode_socket()) { - node_input->get_editor_value_vector(value); - } - else { - zero_v3(value); - } - - SetVectorOperation *op = new SetVectorOperation(); - op->set_vector(value); - add_operation(op); - add_link(op->get_output_socket(), input); - break; - } - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } -} - -void NodeOperationBuilder::resolve_proxies() -{ - Vector proxy_links; - for (const Link &link : links_) { - /* don't replace links from proxy to proxy, since we may need them for replacing others! */ - if (link.from()->get_operation().get_flags().is_proxy_operation && - !link.to()->get_operation().get_flags().is_proxy_operation) - { - proxy_links.append(link); - } - } - - for (const Link &link : proxy_links) { - NodeOperationInput *to = link.to(); - NodeOperationOutput *from = link.from(); - do { - /* walk upstream bypassing the proxy operation */ - from = from->get_operation().get_input_socket(0)->get_link(); - } while (from && from->get_operation().get_flags().is_proxy_operation); - - remove_input_link(to); - /* we may not have a final proxy input link, - * in that case it just gets dropped - */ - if (from) { - add_link(from, to); - } - } -} - -void NodeOperationBuilder::determine_canvases() -{ - /* Determine all canvas areas of the operations. */ - const rcti &preferred_area = COM_AREA_NONE; - for (NodeOperation *op : operations_) { - if (op->is_output_operation(context_->is_rendering()) && !op->get_flags().is_preview_operation) - { - rcti canvas = COM_AREA_NONE; - op->determine_canvas(preferred_area, canvas); - op->set_canvas(canvas); - } - } - - for (NodeOperation *op : operations_) { - if (op->is_output_operation(context_->is_rendering()) && op->get_flags().is_preview_operation) - { - rcti canvas = COM_AREA_NONE; - op->determine_canvas(preferred_area, canvas); - op->set_canvas(canvas); - } - } - - /* Convert operation canvases when needed. */ - { - Vector convert_links; - for (const Link &link : links_) { - if (link.to()->get_resize_mode() != ResizeMode::None) { - const rcti &from_canvas = link.from()->get_operation().get_canvas(); - const rcti &to_canvas = link.to()->get_operation().get_canvas(); - - bool needs_conversion; - if (link.to()->get_resize_mode() == ResizeMode::Align) { - needs_conversion = from_canvas.xmin != to_canvas.xmin || - from_canvas.ymin != to_canvas.ymin; - } - else { - needs_conversion = !BLI_rcti_compare(&from_canvas, &to_canvas); - } - - if (needs_conversion) { - convert_links.append(link); - } - } - } - for (const Link &link : convert_links) { - COM_convert_canvas(*this, link.from(), link.to()); - } - } -} - -static Vector generate_hashes(Span operations) -{ - Vector hashes; - for (NodeOperation *op : operations) { - std::optional hash = op->generate_hash(); - if (hash) { - hashes.append(std::move(*hash)); - } - } - return hashes; -} - -void NodeOperationBuilder::merge_equal_operations() -{ - bool check_for_next_merge = true; - while (check_for_next_merge) { - /* Re-generate hashes with any change. */ - Vector hashes = generate_hashes(operations_); - - /* Make hashes be consecutive when they are equal. */ - std::sort(hashes.begin(), hashes.end()); - - bool any_merged = false; - const NodeOperationHash *prev_hash = nullptr; - for (const NodeOperationHash &hash : hashes) { - if (prev_hash && *prev_hash == hash) { - merge_equal_operations(prev_hash->get_operation(), hash.get_operation()); - any_merged = true; - } - prev_hash = &hash; - } - - check_for_next_merge = any_merged; - } -} - -void NodeOperationBuilder::merge_equal_operations(NodeOperation *from, NodeOperation *into) -{ - unlink_inputs_and_relink_outputs(from, into); - operations_.remove_first_occurrence_and_reorder(from); - delete from; -} - -Vector NodeOperationBuilder::cache_output_links( - NodeOperationOutput *output) const -{ - Vector inputs; - for (const Link &link : links_) { - if (link.from() == output) { - inputs.append(link.to()); - } - } - return inputs; -} - -using Tags = std::set; - -static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op) -{ - if (reachable.find(op) != reachable.end()) { - return; - } - reachable.insert(op); - - for (int i = 0; i < op->get_number_of_input_sockets(); i++) { - NodeOperationInput *input = op->get_input_socket(i); - if (input->is_connected()) { - find_reachable_operations_recursive(reachable, &input->get_link()->get_operation()); - } - } -} - -void NodeOperationBuilder::prune_operations() -{ - Tags reachable; - for (NodeOperation *op : operations_) { - /* output operations are primary executed operations */ - if (op->is_output_operation(context_->is_rendering())) { - find_reachable_operations_recursive(reachable, op); - } - } - - /* delete unreachable operations */ - Vector reachable_ops; - for (NodeOperation *op : operations_) { - if (reachable.find(op) != reachable.end()) { - reachable_ops.append(op); - } - else { - delete op; - } - } - /* finally replace the operations list with the pruned list */ - operations_ = reachable_ops; -} - -/* topological (depth-first) sorting of operations */ -static void sort_operations_recursive(Vector &sorted, - Tags &visited, - NodeOperation *op) -{ - if (visited.find(op) != visited.end()) { - return; - } - visited.insert(op); - - for (int i = 0; i < op->get_number_of_input_sockets(); i++) { - NodeOperationInput *input = op->get_input_socket(i); - if (input->is_connected()) { - sort_operations_recursive(sorted, visited, &input->get_link()->get_operation()); - } - } - - sorted.append(op); -} - -void NodeOperationBuilder::sort_operations() -{ - Vector sorted; - sorted.reserve(operations_.size()); - Tags visited; - - for (NodeOperation *operation : operations_) { - sort_operations_recursive(sorted, visited, operation); - } - - operations_ = sorted; -} - -void NodeOperationBuilder::save_graphviz(StringRefNull name) -{ - if (COM_EXPORT_GRAPHVIZ) { - exec_system_->set_operations(operations_); - DebugInfo::graphviz(exec_system_, name); - } -} - -std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder &builder) -{ - os << "# Builder start\n"; - os << "digraph G {\n"; - os << " rankdir=LR;\n"; - os << " node [shape=box];\n"; - for (const NodeOperation *operation : builder.get_operations()) { - os << " op" << operation->get_id() << " [label=\"" << *operation << "\"];\n"; - } - - os << "\n"; - for (const NodeOperationBuilder::Link &link : builder.get_links()) { - os << " op" << link.from()->get_operation().get_id() << " -> op" - << link.to()->get_operation().get_id() << ";\n"; - } - - os << "}\n"; - os << "# Builder end\n"; - return os; -} - -std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder::Link &link) -{ - os << link.from()->get_operation().get_id() << " -> " << link.to()->get_operation().get_id(); - return os; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h deleted file mode 100644 index 5eb6cf5b754..00000000000 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h +++ /dev/null @@ -1,154 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_map.hh" -#include "BLI_vector.hh" - -#include "COM_NodeGraph.h" - -namespace blender::compositor { - -class CompositorContext; - -class Node; -class NodeInput; -class NodeOutput; - -class ExecutionSystem; -class NodeOperation; -class NodeOperationInput; -class NodeOperationOutput; - -class PreviewOperation; -class ViewerOperation; -class ConstantOperation; - -class NodeOperationBuilder { - public: - class Link { - private: - NodeOperationOutput *from_; - NodeOperationInput *to_; - - public: - Link(NodeOperationOutput *from, NodeOperationInput *to) : from_(from), to_(to) {} - - NodeOperationOutput *from() const - { - return from_; - } - NodeOperationInput *to() const - { - return to_; - } - }; - - private: - const CompositorContext *context_; - NodeGraph graph_; - ExecutionSystem *exec_system_; - - Vector operations_; - Vector links_; - - /** Maps operation inputs to node inputs */ - Map input_map_; - /** Maps node outputs to operation outputs */ - Map output_map_; - - Node *current_node_; - - /** - * Operation that will be writing to the viewer image - * Only one operation can occupy this place at a time, to avoid race conditions. - */ - ViewerOperation *active_viewer_; - - public: - NodeOperationBuilder(const CompositorContext *context, - bNodeTree *b_nodetree, - ExecutionSystem *system); - - const CompositorContext &context() const - { - return *context_; - } - - void convert_to_operations(ExecutionSystem *system); - - void add_operation(NodeOperation *operation); - void replace_operation_with_constant(NodeOperation *operation, - ConstantOperation *constant_operation); - - /** Map input socket of the current node to an operation socket */ - void map_input_socket(NodeInput *node_socket, NodeOperationInput *operation_socket); - /** Map output socket of the current node to an operation socket */ - void map_output_socket(NodeOutput *node_socket, NodeOperationOutput *operation_socket); - - void add_link(NodeOperationOutput *from, NodeOperationInput *to); - void remove_input_link(NodeOperationInput *to); - - /** Add a preview operation for a operation output */ - void add_preview(NodeOperationOutput *output); - /** Add a preview operation for a node input */ - void add_node_input_preview(NodeInput *input); - - /** Define a viewer operation as the active output, if possible */ - void register_viewer(ViewerOperation *viewer); - /** The currently active viewer output operation */ - ViewerOperation *active_viewer() const - { - return active_viewer_; - } - - Span get_operations() const - { - return operations_; - } - - Span get_links() const - { - return links_; - } - - protected: - /** Add datatype conversion where needed */ - void add_datatype_conversions(); - - /** Construct a constant value operation for every unconnected input */ - void add_operation_input_constants(); - void add_input_constant_value(NodeOperationInput *input, const NodeInput *node_input); - - /** Replace proxy operations with direct links */ - void resolve_proxies(); - - /** Calculate canvas area for each operation. */ - void determine_canvases(); - - /** Helper function to store connected inputs for replacement */ - Vector cache_output_links(NodeOperationOutput *output) const; - - /** Remove unreachable operations */ - void prune_operations(); - - /** Sort operations by link dependencies */ - void sort_operations(); - - private: - PreviewOperation *make_preview_operation() const; - void unlink_inputs_and_relink_outputs(NodeOperation *unlinked_op, NodeOperation *linked_op); - /** Merge operations with same type, inputs and parameters that produce the same result. */ - void merge_equal_operations(); - void merge_equal_operations(NodeOperation *from, NodeOperation *into); - void save_graphviz(StringRefNull name = ""); - MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeCompilerImpl") -}; - -/** Create a graphviz representation of the NodeOperationBuilder. */ -std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder &builder); -std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder::Link &link); - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_SharedOperationBuffers.cc b/source/blender/compositor/intern/COM_SharedOperationBuffers.cc deleted file mode 100644 index 964bec27b48..00000000000 --- a/source/blender/compositor/intern/COM_SharedOperationBuffers.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SharedOperationBuffers.h" -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -SharedOperationBuffers::BufferData::BufferData() - : buffer(nullptr), registered_reads(0), received_reads(0), is_rendered(false) -{ -} - -SharedOperationBuffers::BufferData &SharedOperationBuffers::get_buffer_data(NodeOperation *op) -{ - return buffers_.lookup_or_add_cb(op, []() { return BufferData(); }); -} - -bool SharedOperationBuffers::is_area_registered(NodeOperation *op, const rcti &area_to_render) -{ - /* TODO: Possibly refactor to "request_area". Current implementation is incomplete: - * partial overlapping, etc. Leading to more rendering than necessary. */ - - BufferData &buf_data = get_buffer_data(op); - for (rcti ®_rect : buf_data.render_areas) { - if (BLI_rcti_inside_rcti(®_rect, &area_to_render)) { - return true; - } - } - return false; -} - -void SharedOperationBuffers::register_area(NodeOperation *op, const rcti &area_to_render) -{ - get_buffer_data(op).render_areas.append(area_to_render); -} - -bool SharedOperationBuffers::has_registered_reads(NodeOperation *op) -{ - return get_buffer_data(op).registered_reads > 0; -} - -void SharedOperationBuffers::register_read(NodeOperation *read_op) -{ - get_buffer_data(read_op).registered_reads++; -} - -Vector SharedOperationBuffers::get_areas_to_render(NodeOperation *op, - const int offset_x, - const int offset_y) -{ - Span render_areas = get_buffer_data(op).render_areas.as_span(); - Vector dst_areas; - for (rcti dst : render_areas) { - BLI_rcti_translate(&dst, offset_x, offset_y); - dst_areas.append(std::move(dst)); - } - return dst_areas; -} - -bool SharedOperationBuffers::is_operation_rendered(NodeOperation *op) -{ - return get_buffer_data(op).is_rendered; -} - -void SharedOperationBuffers::set_rendered_buffer(NodeOperation *op, - std::unique_ptr buffer) -{ - BufferData &buf_data = get_buffer_data(op); - BLI_assert(buf_data.received_reads == 0); - BLI_assert(buf_data.buffer == nullptr); - buf_data.buffer = std::move(buffer); - buf_data.is_rendered = true; -} - -MemoryBuffer *SharedOperationBuffers::get_rendered_buffer(NodeOperation *op) -{ - BLI_assert(is_operation_rendered(op)); - return get_buffer_data(op).buffer.get(); -} - -void SharedOperationBuffers::read_finished(NodeOperation *read_op) -{ - BufferData &buf_data = get_buffer_data(read_op); - buf_data.received_reads++; - BLI_assert(buf_data.received_reads > 0 && buf_data.received_reads <= buf_data.registered_reads); - if (buf_data.received_reads == buf_data.registered_reads) { - /* Dispose buffer. */ - buf_data.buffer = nullptr; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_SharedOperationBuffers.h b/source/blender/compositor/intern/COM_SharedOperationBuffers.h deleted file mode 100644 index 08dff4db6d4..00000000000 --- a/source/blender/compositor/intern/COM_SharedOperationBuffers.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_map.hh" -#include "BLI_vector.hh" - -#include "DNA_vec_types.h" - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -class MemoryBuffer; -class NodeOperation; - -/** - * Stores and shares operations rendered buffers including render data. Buffers are - * disposed once all dependent operations have finished reading them. - */ -class SharedOperationBuffers { - private: - typedef struct BufferData { - public: - BufferData(); - std::unique_ptr buffer; - blender::Vector render_areas; - int registered_reads; - int received_reads; - bool is_rendered; - } BufferData; - blender::Map buffers_; - - public: - /** - * Whether given operation area to render is already registered. - */ - bool is_area_registered(NodeOperation *op, const rcti &area_to_render); - /** - * Registers an operation area to render. - */ - void register_area(NodeOperation *op, const rcti &area_to_render); - - /** - * Whether given operation has any registered reads (other operation registered it depends on - * given operation). - */ - bool has_registered_reads(NodeOperation *op); - /** - * Registers an operation read (other operation depends on given operation). - */ - void register_read(NodeOperation *read_op); - - /** - * Get registered areas given operation needs to render. - */ - Vector get_areas_to_render(NodeOperation *op, int offset_x, int offset_y); - /** - * Whether this operation buffer has already been rendered. - */ - bool is_operation_rendered(NodeOperation *op); - /** - * Stores given operation rendered buffer. - */ - void set_rendered_buffer(NodeOperation *op, std::unique_ptr buffer); - /** - * Get given operation rendered buffer. - */ - MemoryBuffer *get_rendered_buffer(NodeOperation *op); - - /** - * Reports an operation has finished reading given operation. If all given operation dependencies - * have finished its buffer will be disposed. - */ - void read_finished(NodeOperation *read_op); - - private: - BufferData &get_buffer_data(NodeOperation *op); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:SharedOperationBuffers") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h deleted file mode 100644 index 62221dfda21..00000000000 --- a/source/blender/compositor/intern/COM_WorkPackage.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "MEM_guardedalloc.h" - -#include - -namespace blender::compositor { - -/** - * \brief contains data about work that can be scheduled - * \see WorkScheduler - */ -struct WorkPackage { - /** - * Called to execute work. - */ - std::function execute_fn; - - /** - * Called when work execution is finished. - */ - std::function executed_fn; - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:WorkPackage") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc deleted file mode 100644 index af7b9e7509e..00000000000 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ /dev/null @@ -1,315 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_WorkScheduler.h" - -#include "COM_CPUDevice.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_task.h" -#include "BLI_threads.h" -#include "BLI_vector.hh" - -#include "BKE_global.hh" - -namespace blender::compositor { - -enum class ThreadingModel { - /** Everything is executed in the caller thread. easy for debugging. */ - SingleThreaded, - /** Multi-threaded model, which uses the BLI_thread_queue pattern. */ - Queue, - /** Uses BLI_task as threading backend. */ - Task -}; - -/** - * Returns the active threading model. - * - * Default is `ThreadingModel::Queue`. - */ -constexpr ThreadingModel COM_threading_model() -{ - return ThreadingModel::Queue; -} - -static ThreadLocal(CPUDevice *) g_thread_device; -static struct { - struct { - /** \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is - * created - */ - Vector devices; - - /** \brief list of all thread for every CPUDevice in cpudevices a thread exists. */ - ListBase threads; - bool initialized = false; - /** \brief all scheduled work for the cpu */ - ThreadQueue *queue; - } queue; - - struct { - TaskPool *pool; - } task; - - int num_cpu_threads; -} g_work_scheduler; - -/* -------------------------------------------------------------------- */ -/** \name Single threaded Scheduling - * \{ */ - -static void threading_model_single_thread_execute(WorkPackage *package) -{ - CPUDevice device(0); - device.execute(package); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Queue Scheduling - * \{ */ - -static void *threading_model_queue_execute(void *data) -{ - CPUDevice *device = (CPUDevice *)data; - WorkPackage *work; - BLI_thread_local_set(g_thread_device, device); - while ((work = (WorkPackage *)BLI_thread_queue_pop(g_work_scheduler.queue.queue))) { - device->execute(work); - } - - return nullptr; -} - -static void threading_model_queue_schedule(WorkPackage *package) -{ - BLI_thread_queue_push(g_work_scheduler.queue.queue, package); -} - -static void threading_model_queue_start() -{ - g_work_scheduler.queue.queue = BLI_thread_queue_init(); - BLI_threadpool_init(&g_work_scheduler.queue.threads, - threading_model_queue_execute, - g_work_scheduler.queue.devices.size()); - for (Device &device : g_work_scheduler.queue.devices) { - BLI_threadpool_insert(&g_work_scheduler.queue.threads, &device); - } -} - -static void threading_model_queue_finish() -{ - BLI_thread_queue_wait_finish(g_work_scheduler.queue.queue); -} - -static void threading_model_queue_stop() -{ - BLI_thread_queue_nowait(g_work_scheduler.queue.queue); - BLI_threadpool_end(&g_work_scheduler.queue.threads); - BLI_thread_queue_free(g_work_scheduler.queue.queue); - g_work_scheduler.queue.queue = nullptr; -} - -static void threading_model_queue_initialize(const int num_cpu_threads) -{ - /* Reinitialize if number of threads doesn't match. */ - if (g_work_scheduler.queue.devices.size() != num_cpu_threads) { - g_work_scheduler.queue.devices.clear(); - if (g_work_scheduler.queue.initialized) { - BLI_thread_local_delete(g_thread_device); - g_work_scheduler.queue.initialized = false; - } - } - - /* Initialize CPU threads. */ - if (!g_work_scheduler.queue.initialized) { - for (int index = 0; index < num_cpu_threads; index++) { - g_work_scheduler.queue.devices.append_as(index); - } - BLI_thread_local_create(g_thread_device); - g_work_scheduler.queue.initialized = true; - } -} -static void threading_model_queue_deinitialize() -{ - /* deinitialize CPU threads */ - if (g_work_scheduler.queue.initialized) { - g_work_scheduler.queue.devices.clear_and_shrink(); - - BLI_thread_local_delete(g_thread_device); - g_work_scheduler.queue.initialized = false; - } -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Task Scheduling - * \{ */ - -static void threading_model_task_execute(TaskPool *__restrict /*pool*/, void *task_data) -{ - WorkPackage *package = static_cast(task_data); - CPUDevice device(BLI_task_parallel_thread_id(nullptr)); - BLI_thread_local_set(g_thread_device, &device); - device.execute(package); -} - -static void threading_model_task_schedule(WorkPackage *package) -{ - BLI_task_pool_push( - g_work_scheduler.task.pool, threading_model_task_execute, package, false, nullptr); -} - -static void threading_model_task_start() -{ - BLI_thread_local_create(g_thread_device); - g_work_scheduler.task.pool = BLI_task_pool_create(nullptr, TASK_PRIORITY_HIGH); -} - -static void threading_model_task_finish() -{ - BLI_task_pool_work_and_wait(g_work_scheduler.task.pool); -} - -static void threading_model_task_stop() -{ - BLI_task_pool_free(g_work_scheduler.task.pool); - g_work_scheduler.task.pool = nullptr; - BLI_thread_local_delete(g_thread_device); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Public API - * \{ */ - -void WorkScheduler::schedule(WorkPackage *package) -{ - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: { - threading_model_single_thread_execute(package); - break; - } - - case ThreadingModel::Queue: { - threading_model_queue_schedule(package); - break; - } - - case ThreadingModel::Task: { - threading_model_task_schedule(package); - break; - } - } -} - -void WorkScheduler::start() -{ - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: - /* Nothing to do. */ - break; - - case ThreadingModel::Queue: - threading_model_queue_start(); - break; - - case ThreadingModel::Task: - threading_model_task_start(); - break; - } -} - -void WorkScheduler::finish() -{ - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: - /* Nothing to do. */ - break; - - case ThreadingModel::Queue: - threading_model_queue_finish(); - break; - - case ThreadingModel::Task: - threading_model_task_finish(); - break; - } -} - -void WorkScheduler::stop() -{ - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: - /* Nothing to do. */ - break; - - case ThreadingModel::Queue: - threading_model_queue_stop(); - break; - - case ThreadingModel::Task: - threading_model_task_stop(); - break; - } -} - -void WorkScheduler::initialize(int num_cpu_threads) -{ - g_work_scheduler.num_cpu_threads = num_cpu_threads; - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: - g_work_scheduler.num_cpu_threads = 1; - /* Nothing to do. */ - break; - case ThreadingModel::Queue: - threading_model_queue_initialize(num_cpu_threads); - break; - - case ThreadingModel::Task: - /* Nothing to do. */ - break; - } -} - -void WorkScheduler::deinitialize() -{ - switch (COM_threading_model()) { - case ThreadingModel::SingleThreaded: - /* Nothing to do. */ - break; - - case ThreadingModel::Queue: - threading_model_queue_deinitialize(); - break; - - case ThreadingModel::Task: - /* Nothing to do. */ - break; - } -} - -int WorkScheduler::get_num_cpu_threads() -{ - return g_work_scheduler.num_cpu_threads; -} - -int WorkScheduler::current_thread_id() -{ - if (COM_threading_model() == ThreadingModel::SingleThreaded) { - return 0; - } - - CPUDevice *device = (CPUDevice *)BLI_thread_local_get(g_thread_device); - return device->thread_id(); -} - -/** \} */ - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h deleted file mode 100644 index 78368aef5a7..00000000000 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "MEM_guardedalloc.h" - -namespace blender::compositor { - -struct WorkPackage; - -/** \brief the workscheduler - * \ingroup execution - */ -struct WorkScheduler { - /** - * \brief schedule a chunk of a group to be calculated. - * An execution group schedules a chunk in the WorkScheduler - */ - static void schedule(WorkPackage *package); - - /** - * \brief initialize the WorkScheduler - * - * during initialization the mutexes are initialized. - * there are two mutexes (for every device type one) - * After mutex initialization the system is queried in order to count the number of CPUDevices - * to be created. For every hardware thread a CPUDevice is created. - */ - static void initialize(int num_cpu_threads); - - /** - * \brief deinitialize the WorkScheduler - * free all allocated resources - */ - static void deinitialize(); - - /** - * \brief Start the execution - * this methods will start the WorkScheduler. Inside this method all threads are initialized. - * for every device a thread is created. - * \see initialize Initialization and query of the number of devices - */ - static void start(); - - /** - * \brief stop the execution - * All created thread by the start method are destroyed. - * \see start - */ - static void stop(); - - /** - * \brief wait for all work to be completed. - */ - static void finish(); - - static int get_num_cpu_threads(); - - static int current_thread_id(); - - MEM_CXX_CLASS_ALLOC_FUNCS("COM:WorkScheduler") -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/intern/COM_compositor.cc b/source/blender/compositor/intern/COM_compositor.cc index 43b50327bfe..a32f181dc3a 100644 --- a/source/blender/compositor/intern/COM_compositor.cc +++ b/source/blender/compositor/intern/COM_compositor.cc @@ -6,18 +6,16 @@ #include "BLT_translation.hh" -#include "DNA_userdef_types.h" - #include "BKE_node.hh" #include "BKE_node_runtime.hh" #include "BKE_scene.hh" -#include "COM_ExecutionSystem.h" -#include "COM_WorkScheduler.h" #include "COM_compositor.hh" #include "RE_compositor.hh" +static constexpr float COM_PREVIEW_SIZE = 140.f; + static struct { bool is_initialized = false; ThreadMutex mutex; @@ -35,12 +33,12 @@ static void compositor_init_node_previews(const RenderData *render_data, bNodeTr 1.0f; int preview_width, preview_height; if (aspect < 1.0f) { - preview_width = blender::compositor::COM_PREVIEW_SIZE; - preview_height = int(blender::compositor::COM_PREVIEW_SIZE * aspect); + preview_width = COM_PREVIEW_SIZE; + preview_height = int(COM_PREVIEW_SIZE * aspect); } else { - preview_width = int(blender::compositor::COM_PREVIEW_SIZE / aspect); - preview_height = blender::compositor::COM_PREVIEW_SIZE; + preview_width = int(COM_PREVIEW_SIZE / aspect); + preview_height = COM_PREVIEW_SIZE; } blender::bke::node_preview_init_tree(node_tree, preview_width, preview_height); } @@ -90,7 +88,6 @@ void COM_deinitialize() { if (g_compositor.is_initialized) { BLI_mutex_lock(&g_compositor.mutex); - blender::compositor::WorkScheduler::deinitialize(); g_compositor.is_initialized = false; BLI_mutex_unlock(&g_compositor.mutex); BLI_mutex_end(&g_compositor.mutex); diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.cc b/source/blender/compositor/nodes/COM_AlphaOverNode.cc deleted file mode 100644 index 07007d4e918..00000000000 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_AlphaOverNode.h" - -#include "COM_AlphaOverKeyOperation.h" -#include "COM_AlphaOverMixedOperation.h" -#include "COM_AlphaOverPremultiplyOperation.h" - -namespace blender::compositor { - -void AlphaOverNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *color1Socket = this->get_input_socket(1); - NodeInput *color2Socket = this->get_input_socket(2); - const bNode *editor_node = this->get_bnode(); - - MixBaseOperation *convert_prog; - const NodeTwoFloats *ntf = (const NodeTwoFloats *)editor_node->storage; - if (ntf->x != 0.0f) { - AlphaOverMixedOperation *mix_operation = new AlphaOverMixedOperation(); - mix_operation->setX(ntf->x); - convert_prog = mix_operation; - } - else if (editor_node->custom1) { - convert_prog = new AlphaOverKeyOperation(); - } - else { - convert_prog = new AlphaOverPremultiplyOperation(); - } - - convert_prog->set_use_value_alpha_multiply(false); - if (color1Socket->is_linked()) { - convert_prog->set_canvas_input_index(1); - } - else if (color2Socket->is_linked()) { - convert_prog->set_canvas_input_index(2); - } - else { - convert_prog->set_canvas_input_index(0); - } - - converter.add_operation(convert_prog); - converter.map_input_socket(get_input_socket(0), convert_prog->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), convert_prog->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), convert_prog->get_input_socket(2)); - converter.map_output_socket(get_output_socket(0), convert_prog->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h deleted file mode 100644 index 4074776b6a0..00000000000 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief AlphaOverNode - * \ingroup Node - */ -class AlphaOverNode : public Node { - public: - AlphaOverNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_AntiAliasingNode.cc b/source/blender/compositor/nodes/COM_AntiAliasingNode.cc deleted file mode 100644 index 3b73bdc4f1b..00000000000 --- a/source/blender/compositor/nodes/COM_AntiAliasingNode.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-FileCopyrightText: 2017 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_AntiAliasingNode.h" -#include "COM_SMAAOperation.h" - -namespace blender::compositor { - -/* Blender encodes the threshold in the [0, 1] range, while the SMAA algorithm expects it in - * the [0, 0.5] range. */ -static float get_threshold(const NodeAntiAliasingData *data) -{ - return data->threshold / 2.0f; -} - -/* Blender encodes the local contrast adaptation factor in the [0, 1] range, while the SMAA - * algorithm expects it in the [0, 10] range. */ -static float get_local_contrast_adaptation_factor(const NodeAntiAliasingData *data) -{ - return data->contrast_limit * 10.0f; -} - -/* Blender encodes the corner rounding factor in the float [0, 1] range, while the SMAA algorithm - * expects it in the integer [0, 100] range. */ -static int get_corner_rounding(const NodeAntiAliasingData *data) -{ - return int(data->corner_rounding * 100.0f); -} - -void AntiAliasingNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - const NodeAntiAliasingData *data = (const NodeAntiAliasingData *)node->storage; - - SMAAOperation *operation = new SMAAOperation(); - operation->set_threshold(get_threshold(data)); - operation->set_local_contrast_adaptation_factor(get_local_contrast_adaptation_factor(data)); - operation->set_corner_rounding(get_corner_rounding(data)); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_AntiAliasingNode.h b/source/blender/compositor/nodes/COM_AntiAliasingNode.h deleted file mode 100644 index a18f6d4dd0e..00000000000 --- a/source/blender/compositor/nodes/COM_AntiAliasingNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2017 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief AntiAliasingNode - * \ingroup Node - */ -class AntiAliasingNode : public Node { - public: - AntiAliasingNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.cc b/source/blender/compositor/nodes/COM_BilateralBlurNode.cc deleted file mode 100644 index 9f1d94bcac6..00000000000 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BilateralBlurNode.h" -#include "COM_BilateralBlurOperation.h" - -namespace blender::compositor { - -BilateralBlurNode::BilateralBlurNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BilateralBlurNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeBilateralBlurData *data = (NodeBilateralBlurData *)this->get_bnode()->storage; - BilateralBlurOperation *operation = new BilateralBlurOperation(); - operation->set_data(data); - - converter.add_operation(operation); - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h deleted file mode 100644 index dd073e10526..00000000000 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BilateralBlurNode - * \ingroup Node - */ -class BilateralBlurNode : public Node { - public: - BilateralBlurNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BlurNode.cc b/source/blender/compositor/nodes/COM_BlurNode.cc deleted file mode 100644 index e40c1cfb66d..00000000000 --- a/source/blender/compositor/nodes/COM_BlurNode.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BlurNode.h" -#include "COM_FastGaussianBlurOperation.h" -#include "COM_GammaCorrectOperation.h" -#include "COM_GaussianAlphaBlurBaseOperation.h" -#include "COM_GaussianBlurBaseOperation.h" -#include "COM_GaussianBokehBlurOperation.h" -#include "COM_MathBaseOperation.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -BlurNode::BlurNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BlurNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - const NodeBlurData *data = (const NodeBlurData *)editor_node->storage; - NodeInput *input_size_socket = this->get_input_socket(1); - bool connected_size_socket = input_size_socket->is_linked(); - - const float size = this->get_input_socket(1)->get_editor_value_float(); - const bool extend_bounds = (editor_node->custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS) != 0; - - NodeOperation *input_operation = nullptr, *output_operation = nullptr; - - if (data->filtertype == R_FILTER_FAST_GAUSS) { - FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); - operationfgb->set_data(data); - operationfgb->set_extend_bounds(extend_bounds); - converter.add_operation(operationfgb); - - converter.map_input_socket(get_input_socket(1), operationfgb->get_input_socket(1)); - - input_operation = operationfgb; - output_operation = operationfgb; - } - else if ((editor_node->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) && connected_size_socket) { - MathAddOperation *clamp = new MathAddOperation(); - SetValueOperation *zero = new SetValueOperation(); - zero->set_value(0.0f); - clamp->set_use_clamp(true); - - converter.add_operation(clamp); - converter.add_operation(zero); - converter.map_input_socket(get_input_socket(1), clamp->get_input_socket(0)); - converter.add_link(zero->get_output_socket(), clamp->get_input_socket(1)); - - GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation(); - operation->set_data(data); - operation->set_extend_bounds(extend_bounds); - - converter.add_operation(operation); - converter.add_link(clamp->get_output_socket(), operation->get_input_socket(1)); - - output_operation = operation; - input_operation = operation; - } - else if (!data->bokeh) { - GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); - operationx->set_data(data); - operationx->set_extend_bounds(extend_bounds); - - converter.add_operation(operationx); - converter.map_input_socket(get_input_socket(1), operationx->get_input_socket(1)); - - GaussianYBlurOperation *operationy = new GaussianYBlurOperation(); - operationy->set_data(data); - operationy->set_extend_bounds(extend_bounds); - - converter.add_operation(operationy); - converter.map_input_socket(get_input_socket(1), operationy->get_input_socket(1)); - converter.add_link(operationx->get_output_socket(), operationy->get_input_socket(0)); - - if (!connected_size_socket) { - operationx->set_size(size); - operationy->set_size(size); - } - - input_operation = operationx; - output_operation = operationy; - } - else { - GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation(); - operation->set_data(data); - operation->set_extend_bounds(extend_bounds); - - converter.add_operation(operation); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - - if (!connected_size_socket) { - operation->set_size(size); - } - - input_operation = operation; - output_operation = operation; - } - - if (data->gamma) { - GammaCorrectOperation *correct = new GammaCorrectOperation(); - GammaUncorrectOperation *inverse = new GammaUncorrectOperation(); - converter.add_operation(correct); - converter.add_operation(inverse); - - converter.map_input_socket(get_input_socket(0), correct->get_input_socket(0)); - converter.add_link(correct->get_output_socket(), input_operation->get_input_socket(0)); - converter.add_link(output_operation->get_output_socket(), inverse->get_input_socket(0)); - converter.map_output_socket(get_output_socket(), inverse->get_output_socket()); - - converter.add_preview(inverse->get_output_socket()); - } - else { - converter.map_input_socket(get_input_socket(0), input_operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(), output_operation->get_output_socket()); - - converter.add_preview(output_operation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h deleted file mode 100644 index 6385df0bfb0..00000000000 --- a/source/blender/compositor/nodes/COM_BlurNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BlurNode - * \ingroup Node - */ -class BlurNode : public Node { - public: - BlurNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cc b/source/blender/compositor/nodes/COM_BokehBlurNode.cc deleted file mode 100644 index 986bc603d4c..00000000000 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BokehBlurNode.h" -#include "COM_BokehBlurOperation.h" -#include "COM_VariableSizeBokehBlurOperation.h" - -namespace blender::compositor { - -BokehBlurNode::BokehBlurNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BokehBlurNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *b_node = this->get_bnode(); - - NodeInput *input_size_socket = this->get_input_socket(2); - - bool connected_size_socket = input_size_socket->is_linked(); - const bool extend_bounds = (b_node->custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS) != 0; - - if ((b_node->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) && connected_size_socket) { - VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); - operation->set_threshold(0.0f); - operation->set_max_blur(b_node->custom4); - operation->set_do_scale_size(true); - - converter.add_operation(operation); - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - } - else { - BokehBlurOperation *operation = new BokehBlurOperation(); - operation->set_extend_bounds(extend_bounds); - - converter.add_operation(operation); - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - - /* NOTE: on the bokeh blur operation the sockets are switched. - * for this reason the next two lines are correct. Fix for #43771. */ - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(3)); - converter.map_input_socket(get_input_socket(3), operation->get_input_socket(2)); - - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - - if (!connected_size_socket) { - operation->set_size(this->get_input_socket(2)->get_editor_value_float()); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h deleted file mode 100644 index 1965fb28cec..00000000000 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BokehBlurNode - * \ingroup Node - */ -class BokehBlurNode : public Node { - public: - BokehBlurNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.cc b/source/blender/compositor/nodes/COM_BokehImageNode.cc deleted file mode 100644 index 432a13521ba..00000000000 --- a/source/blender/compositor/nodes/COM_BokehImageNode.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BokehImageNode.h" -#include "COM_BokehImageOperation.h" - -namespace blender::compositor { - -BokehImageNode::BokehImageNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BokehImageNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - BokehImageOperation *operation = new BokehImageOperation(); - operation->set_data((const NodeBokehImage *)this->get_bnode()->storage); - - converter.add_operation(operation); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - - converter.add_preview(operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h deleted file mode 100644 index b0cba89c600..00000000000 --- a/source/blender/compositor/nodes/COM_BokehImageNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BokehImageNode - * \ingroup Node - */ -class BokehImageNode : public Node { - public: - BokehImageNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.cc b/source/blender/compositor/nodes/COM_BoxMaskNode.cc deleted file mode 100644 index da1548dcf02..00000000000 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BoxMaskNode.h" -#include "COM_BoxMaskOperation.h" - -#include "COM_ScaleOperation.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -BoxMaskNode::BoxMaskNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BoxMaskNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - - BoxMaskOperation *operation; - operation = new BoxMaskOperation(); - operation->set_data((const NodeBoxMask *)this->get_bnode()->storage); - operation->set_mask_type(this->get_bnode()->custom1); - converter.add_operation(operation); - - if (input_socket->is_linked()) { - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket()); - } - else { - /* Value operation to produce original transparent image */ - SetValueOperation *value_operation = new SetValueOperation(); - value_operation->set_value(0.0f); - converter.add_operation(value_operation); - - /* Scale that image up to render resolution */ - const RenderData *rd = context.get_render_data(); - const float render_size_factor = context.get_render_percentage_as_factor(); - ScaleFixedSizeOperation *scale_operation = new ScaleFixedSizeOperation(); - - scale_operation->set_is_aspect(false); - scale_operation->set_is_crop(false); - scale_operation->set_offset(0.0f, 0.0f); - scale_operation->set_new_width(rd->xsch * render_size_factor); - scale_operation->set_new_height(rd->ysch * render_size_factor); - scale_operation->get_input_socket(0)->set_resize_mode(ResizeMode::Align); - converter.add_operation(scale_operation); - - converter.add_link(value_operation->get_output_socket(0), - scale_operation->get_input_socket(0)); - converter.add_link(scale_operation->get_output_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - } - - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h deleted file mode 100644 index a43b5ec3719..00000000000 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BoxMaskNode - * \ingroup Node - */ -class BoxMaskNode : public Node { - public: - BoxMaskNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cc b/source/blender/compositor/nodes/COM_BrightnessNode.cc deleted file mode 100644 index 72c9410156d..00000000000 --- a/source/blender/compositor/nodes/COM_BrightnessNode.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BrightnessNode.h" -#include "COM_BrightnessOperation.h" - -namespace blender::compositor { - -BrightnessNode::BrightnessNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void BrightnessNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *bnode = this->get_bnode(); - BrightnessOperation *operation = new BrightnessOperation(); - operation->set_use_premultiply((bnode->custom1 & 1) != 0); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h deleted file mode 100644 index a54a316f5dd..00000000000 --- a/source/blender/compositor/nodes/COM_BrightnessNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief BrightnessNode - * \ingroup Node - */ -class BrightnessNode : public Node { - public: - BrightnessNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.cc b/source/blender/compositor/nodes/COM_ChannelMatteNode.cc deleted file mode 100644 index 8ae5a50259b..00000000000 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ChannelMatteNode.h" -#include "COM_ChannelMatteOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -ChannelMatteNode::ChannelMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ChannelMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - - NodeInput *input_socket_image = this->get_input_socket(0); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - - NodeOperation *convert = nullptr, *inv_convert = nullptr; - /* color-space */ - switch (node->custom1) { - case CMP_NODE_CHANNEL_MATTE_CS_RGB: - break; - case CMP_NODE_CHANNEL_MATTE_CS_HSV: /* HSV */ - convert = new ConvertRGBToHSVOperation(); - inv_convert = new ConvertHSVToRGBOperation(); - break; - case CMP_NODE_CHANNEL_MATTE_CS_YUV: /* YUV */ - convert = new ConvertRGBToYUVOperation(); - inv_convert = new ConvertYUVToRGBOperation(); - break; - case CMP_NODE_CHANNEL_MATTE_CS_YCC: /* YCC */ - convert = new ConvertRGBToYCCOperation(); - ((ConvertRGBToYCCOperation *)convert)->set_mode(BLI_YCC_ITU_BT709); - inv_convert = new ConvertYCCToRGBOperation(); - ((ConvertYCCToRGBOperation *)inv_convert)->set_mode(BLI_YCC_ITU_BT709); - break; - default: - break; - } - - ChannelMatteOperation *operation = new ChannelMatteOperation(); - /* pass the ui properties to the operation */ - operation->set_settings((NodeChroma *)node->storage, node->custom2); - converter.add_operation(operation); - - SetAlphaMultiplyOperation *operation_alpha = new SetAlphaMultiplyOperation(); - converter.add_operation(operation_alpha); - - if (convert != nullptr) { - converter.add_operation(convert); - - converter.map_input_socket(input_socket_image, convert->get_input_socket(0)); - converter.add_link(convert->get_output_socket(), operation->get_input_socket(0)); - converter.add_link(convert->get_output_socket(), operation_alpha->get_input_socket(0)); - } - else { - converter.map_input_socket(input_socket_image, operation->get_input_socket(0)); - converter.map_input_socket(input_socket_image, operation_alpha->get_input_socket(0)); - } - - converter.map_output_socket(output_socket_matte, operation->get_output_socket(0)); - converter.add_link(operation->get_output_socket(), operation_alpha->get_input_socket(1)); - - if (inv_convert != nullptr) { - converter.add_operation(inv_convert); - converter.add_link(operation_alpha->get_output_socket(0), inv_convert->get_input_socket(0)); - converter.map_output_socket(output_socket_image, inv_convert->get_output_socket()); - converter.add_preview(inv_convert->get_output_socket()); - } - else { - converter.map_output_socket(output_socket_image, operation_alpha->get_output_socket()); - converter.add_preview(operation_alpha->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h deleted file mode 100644 index 974aad0139e..00000000000 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ChannelMatteNode - * \ingroup Node - */ -class ChannelMatteNode : public Node { - public: - ChannelMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.cc b/source/blender/compositor/nodes/COM_ChromaMatteNode.cc deleted file mode 100644 index 2ae0aa65b5d..00000000000 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ChromaMatteNode.h" -#include "COM_ChromaMatteOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -ChromaMatteNode::ChromaMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ChromaMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editorsnode = get_bnode(); - - NodeInput *input_socket_image = this->get_input_socket(0); - NodeInput *input_socket_key = this->get_input_socket(1); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - - ConvertRGBToYCCOperation *operationRGBToYCC_Image = new ConvertRGBToYCCOperation(); - ConvertRGBToYCCOperation *operationRGBToYCC_Key = new ConvertRGBToYCCOperation(); - operationRGBToYCC_Image->set_mode(BLI_YCC_ITU_BT709); - operationRGBToYCC_Key->set_mode(BLI_YCC_ITU_BT709); - converter.add_operation(operationRGBToYCC_Image); - converter.add_operation(operationRGBToYCC_Key); - - ChromaMatteOperation *operation = new ChromaMatteOperation(); - operation->set_settings((NodeChroma *)editorsnode->storage); - converter.add_operation(operation); - - SetAlphaMultiplyOperation *operation_alpha = new SetAlphaMultiplyOperation(); - converter.add_operation(operation_alpha); - - converter.map_input_socket(input_socket_image, operationRGBToYCC_Image->get_input_socket(0)); - converter.map_input_socket(input_socket_key, operationRGBToYCC_Key->get_input_socket(0)); - converter.add_link(operationRGBToYCC_Image->get_output_socket(), operation->get_input_socket(0)); - converter.add_link(operationRGBToYCC_Key->get_output_socket(), operation->get_input_socket(1)); - converter.map_output_socket(output_socket_matte, operation->get_output_socket()); - - converter.map_input_socket(input_socket_image, operation_alpha->get_input_socket(0)); - converter.add_link(operation->get_output_socket(), operation_alpha->get_input_socket(1)); - converter.map_output_socket(output_socket_image, operation_alpha->get_output_socket()); - - converter.add_preview(operation_alpha->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h deleted file mode 100644 index d2973816e7b..00000000000 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ChromaMatteNode - * \ingroup Node - */ -class ChromaMatteNode : public Node { - public: - ChromaMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cc b/source/blender/compositor/nodes/COM_ColorBalanceNode.cc deleted file mode 100644 index d0d67af9131..00000000000 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorBalanceNode.h" -#include "COM_ColorBalanceASCCDLOperation.h" -#include "COM_ColorBalanceLGGOperation.h" -#include "COM_ColorBalanceWhitepointOperation.h" - -namespace blender::compositor { - -ColorBalanceNode::ColorBalanceNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorBalanceNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - NodeColorBalance *n = (NodeColorBalance *)node->storage; - - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_image_socket = this->get_input_socket(1); - NodeOutput *output_socket = this->get_output_socket(0); - - NodeOperation *operation; - if (node->custom1 == CMP_NODE_COLOR_BALANCE_LGG) { - ColorBalanceLGGOperation *operationLGG = new ColorBalanceLGGOperation(); - - float lift_lgg[3], gamma_inv[3]; - for (int c = 0; c < 3; c++) { - lift_lgg[c] = 2.0f - n->lift[c]; - gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f; - } - - operationLGG->set_gain(n->gain); - operationLGG->set_lift(lift_lgg); - operationLGG->set_gamma_inv(gamma_inv); - operation = operationLGG; - } - else if (node->custom1 == CMP_NODE_COLOR_BALANCE_ASC_CDL) { - ColorBalanceASCCDLOperation *operationCDL = new ColorBalanceASCCDLOperation(); - - float offset[3]; - copy_v3_fl(offset, n->offset_basis); - add_v3_v3(offset, n->offset); - - operationCDL->set_offset(offset); - operationCDL->set_power(n->power); - operationCDL->set_slope(n->slope); - operation = operationCDL; - } - else { - ColorBalanceWhitepointOperation *operation_whitepoint = new ColorBalanceWhitepointOperation(); - operation_whitepoint->set_parameters( - n->input_temperature, n->input_tint, n->output_temperature, n->output_tint); - operation = operation_whitepoint; - } - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_image_socket, operation->get_input_socket(1)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h deleted file mode 100644 index fe9fe5366ae..00000000000 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorBalanceNode - * \ingroup Node - */ -class ColorBalanceNode : public Node { - public: - ColorBalanceNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cc b/source/blender/compositor/nodes/COM_ColorCorrectionNode.cc deleted file mode 100644 index 264743c69a5..00000000000 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorCorrectionNode.h" -#include "COM_ColorCorrectionOperation.h" - -namespace blender::compositor { - -ColorCorrectionNode::ColorCorrectionNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorCorrectionNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = get_bnode(); - - ColorCorrectionOperation *operation = new ColorCorrectionOperation(); - operation->set_data((NodeColorCorrection *)editor_node->storage); - operation->set_red_channel_enabled((editor_node->custom1 & 1) != 0); - operation->set_green_channel_enabled((editor_node->custom1 & 2) != 0); - operation->set_blue_channel_enabled((editor_node->custom1 & 4) != 0); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h deleted file mode 100644 index f7ae960257b..00000000000 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorCorrectionNode - * \ingroup Node - */ -class ColorCorrectionNode : public Node { - public: - ColorCorrectionNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cc b/source/blender/compositor/nodes/COM_ColorCurveNode.cc deleted file mode 100644 index 08bc3997b52..00000000000 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorCurveNode.h" -#include "COM_ColorCurveOperation.h" - -namespace blender::compositor { - -ColorCurveNode::ColorCurveNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorCurveNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - if (this->get_input_socket(2)->is_linked() || this->get_input_socket(3)->is_linked()) { - ColorCurveOperation *operation = new ColorCurveOperation(); - operation->set_curve_mapping((const CurveMapping *)this->get_bnode()->storage); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3)); - - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - } - else { - ConstantLevelColorCurveOperation *operation = new ConstantLevelColorCurveOperation(); - float col[4]; - this->get_input_socket(2)->get_editor_value_color(col); - operation->set_black_level(col); - this->get_input_socket(3)->get_editor_value_color(col); - operation->set_white_level(col); - operation->set_curve_mapping((const CurveMapping *)this->get_bnode()->storage); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h deleted file mode 100644 index 63c3f2ee227..00000000000 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorCurveNode - * \ingroup Node - */ -class ColorCurveNode : public Node { - public: - ColorCurveNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorExposureNode.cc b/source/blender/compositor/nodes/COM_ColorExposureNode.cc deleted file mode 100644 index cad38dd0f7d..00000000000 --- a/source/blender/compositor/nodes/COM_ColorExposureNode.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2020 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorExposureNode.h" -#include "COM_ColorExposureOperation.h" - -namespace blender::compositor { - -ExposureNode::ExposureNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ExposureNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - ExposureOperation *operation = new ExposureOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorExposureNode.h b/source/blender/compositor/nodes/COM_ColorExposureNode.h deleted file mode 100644 index bea8cfb31c9..00000000000 --- a/source/blender/compositor/nodes/COM_ColorExposureNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2020 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ExposureNode - * \ingroup Node - */ -class ExposureNode : public Node { - public: - ExposureNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.cc b/source/blender/compositor/nodes/COM_ColorMatteNode.cc deleted file mode 100644 index 53101fe641a..00000000000 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorMatteNode.h" -#include "COM_ColorMatteOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -ColorMatteNode::ColorMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editorsnode = get_bnode(); - - NodeInput *input_socket_image = this->get_input_socket(0); - NodeInput *input_socket_key = this->get_input_socket(1); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - - ConvertRGBToHSVOperation *operationRGBToHSV_Image = new ConvertRGBToHSVOperation(); - ConvertRGBToHSVOperation *operationRGBToHSV_Key = new ConvertRGBToHSVOperation(); - converter.add_operation(operationRGBToHSV_Image); - converter.add_operation(operationRGBToHSV_Key); - - ColorMatteOperation *operation = new ColorMatteOperation(); - operation->set_settings((NodeChroma *)editorsnode->storage); - converter.add_operation(operation); - - SetAlphaMultiplyOperation *operation_alpha = new SetAlphaMultiplyOperation(); - converter.add_operation(operation_alpha); - - converter.map_input_socket(input_socket_image, operationRGBToHSV_Image->get_input_socket(0)); - converter.map_input_socket(input_socket_key, operationRGBToHSV_Key->get_input_socket(0)); - converter.add_link(operationRGBToHSV_Image->get_output_socket(), operation->get_input_socket(0)); - converter.add_link(operationRGBToHSV_Key->get_output_socket(), operation->get_input_socket(1)); - converter.map_output_socket(output_socket_matte, operation->get_output_socket(0)); - - converter.map_input_socket(input_socket_image, operation_alpha->get_input_socket(0)); - converter.add_link(operation->get_output_socket(), operation_alpha->get_input_socket(1)); - converter.map_output_socket(output_socket_image, operation_alpha->get_output_socket()); - - converter.add_preview(operation_alpha->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h deleted file mode 100644 index 846c2627d89..00000000000 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorMatteNode - * \ingroup Node - */ -class ColorMatteNode : public Node { - public: - ColorMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorNode.cc b/source/blender/compositor/nodes/COM_ColorNode.cc deleted file mode 100644 index b757bd3ab05..00000000000 --- a/source/blender/compositor/nodes/COM_ColorNode.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorNode.h" -#include "COM_SetColorOperation.h" - -namespace blender::compositor { - -ColorNode::ColorNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - SetColorOperation *operation = new SetColorOperation(); - NodeOutput *output = this->get_output_socket(0); - float col[4]; - output->get_editor_value_color(col); - operation->set_channels(col); - converter.add_operation(operation); - - converter.map_output_socket(output, operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h deleted file mode 100644 index 33cb210709f..00000000000 --- a/source/blender/compositor/nodes/COM_ColorNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorNode - * \ingroup Node - */ -class ColorNode : public Node { - public: - ColorNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.cc b/source/blender/compositor/nodes/COM_ColorRampNode.cc deleted file mode 100644 index fa454999e16..00000000000 --- a/source/blender/compositor/nodes/COM_ColorRampNode.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorRampNode.h" -#include "COM_ColorRampOperation.h" -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -ColorRampNode::ColorRampNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorRampNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - NodeOutput *output_socket_alpha = this->get_output_socket(1); - const bNode *editor_node = this->get_bnode(); - - ColorRampOperation *operation = new ColorRampOperation(); - operation->set_color_band((ColorBand *)editor_node->storage); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - - SeparateChannelOperation *operation2 = new SeparateChannelOperation(); - operation2->set_channel(3); - converter.add_operation(operation2); - - converter.add_link(operation->get_output_socket(), operation2->get_input_socket(0)); - converter.map_output_socket(output_socket_alpha, operation2->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h deleted file mode 100644 index 3bf5d05a7a0..00000000000 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorRampNode - * \ingroup Node - */ -class ColorRampNode : public Node { - public: - ColorRampNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.cc b/source/blender/compositor/nodes/COM_ColorSpillNode.cc deleted file mode 100644 index 01a938a4fa4..00000000000 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorSpillNode.h" -#include "COM_ColorSpillOperation.h" - -namespace blender::compositor { - -ColorSpillNode::ColorSpillNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorSpillNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editorsnode = get_bnode(); - - NodeInput *input_socket_image = this->get_input_socket(0); - NodeInput *input_socket_fac = this->get_input_socket(1); - NodeOutput *output_socket_image = this->get_output_socket(0); - - ColorSpillOperation *operation; - operation = new ColorSpillOperation(); - operation->set_settings((NodeColorspill *)editorsnode->storage); - operation->set_spill_channel(editorsnode->custom1 - 1); /* Channel for spilling */ - operation->set_spill_method(editorsnode->custom2); /* Channel method */ - converter.add_operation(operation); - - converter.map_input_socket(input_socket_image, operation->get_input_socket(0)); - converter.map_input_socket(input_socket_fac, operation->get_input_socket(1)); - converter.map_output_socket(output_socket_image, operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h deleted file mode 100644 index f990613093f..00000000000 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ColorSpillNode - * \ingroup Node - */ -class ColorSpillNode : public Node { - public: - ColorSpillNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.cc b/source/blender/compositor/nodes/COM_ColorToBWNode.cc deleted file mode 100644 index d6fbd4090be..00000000000 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorToBWNode.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -ColorToBWNode::ColorToBWNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ColorToBWNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *color_socket = this->get_input_socket(0); - NodeOutput *value_socket = this->get_output_socket(0); - - ConvertColorToBWOperation *convert_prog = new ConvertColorToBWOperation(); - converter.add_operation(convert_prog); - - converter.map_input_socket(color_socket, convert_prog->get_input_socket(0)); - converter.map_output_socket(value_socket, convert_prog->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h deleted file mode 100644 index fa1ec68d785..00000000000 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief ColorToBWNode - * \ingroup Node - */ -class ColorToBWNode : public Node { - public: - ColorToBWNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cc b/source/blender/compositor/nodes/COM_CombineColorNode.cc deleted file mode 100644 index 896a811d3b6..00000000000 --- a/source/blender/compositor/nodes/COM_CombineColorNode.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CombineColorNode.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -CombineColorNode::CombineColorNode(bNode *editor_node) : Node(editor_node) {} - -void CombineColorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_rsocket = this->get_input_socket(0); - NodeInput *input_gsocket = this->get_input_socket(1); - NodeInput *input_bsocket = this->get_input_socket(2); - NodeInput *input_asocket = this->get_input_socket(3); - NodeOutput *output_socket = this->get_output_socket(0); - - CombineChannelsOperation *operation = new CombineChannelsOperation(); - if (input_rsocket->is_linked()) { - operation->set_canvas_input_index(0); - } - else if (input_gsocket->is_linked()) { - operation->set_canvas_input_index(1); - } - else if (input_bsocket->is_linked()) { - operation->set_canvas_input_index(2); - } - else { - operation->set_canvas_input_index(3); - } - converter.add_operation(operation); - - converter.map_input_socket(input_rsocket, operation->get_input_socket(0)); - converter.map_input_socket(input_gsocket, operation->get_input_socket(1)); - converter.map_input_socket(input_bsocket, operation->get_input_socket(2)); - converter.map_input_socket(input_asocket, operation->get_input_socket(3)); - - const bNode *editor_node = this->get_bnode(); - NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)editor_node->storage; - - NodeOperation *color_conv = nullptr; - switch (storage->mode) { - case CMP_NODE_COMBSEP_COLOR_RGB: { - /* Pass */ - break; - } - case CMP_NODE_COMBSEP_COLOR_HSV: { - color_conv = new ConvertHSVToRGBOperation(); - break; - } - case CMP_NODE_COMBSEP_COLOR_HSL: { - color_conv = new ConvertHSLToRGBOperation(); - break; - } - case CMP_NODE_COMBSEP_COLOR_YCC: { - ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation(); - operation->set_mode(storage->ycc_mode); - color_conv = operation; - break; - } - case CMP_NODE_COMBSEP_COLOR_YUV: { - color_conv = new ConvertYUVToRGBOperation(); - break; - } - default: { - BLI_assert_unreachable(); - break; - } - } - - if (color_conv) { - converter.add_operation(color_conv); - - converter.add_link(operation->get_output_socket(), color_conv->get_input_socket(0)); - converter.map_output_socket(output_socket, color_conv->get_output_socket()); - } - else { - converter.map_output_socket(output_socket, operation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.h b/source/blender/compositor/nodes/COM_CombineColorNode.h deleted file mode 100644 index 43817c54d6a..00000000000 --- a/source/blender/compositor/nodes/COM_CombineColorNode.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -class CombineColorNode : public Node { - public: - CombineColorNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.cc b/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.cc deleted file mode 100644 index e2d60170a61..00000000000 --- a/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CombineColorNodeLegacy.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -CombineColorNodeLegacy::CombineColorNodeLegacy(bNode *editor_node) : Node(editor_node) {} - -void CombineColorNodeLegacy::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeInput *input_rsocket = this->get_input_socket(0); - NodeInput *input_gsocket = this->get_input_socket(1); - NodeInput *input_bsocket = this->get_input_socket(2); - NodeInput *input_asocket = this->get_input_socket(3); - NodeOutput *output_socket = this->get_output_socket(0); - - CombineChannelsOperation *operation = new CombineChannelsOperation(); - if (input_rsocket->is_linked()) { - operation->set_canvas_input_index(0); - } - else if (input_gsocket->is_linked()) { - operation->set_canvas_input_index(1); - } - else if (input_bsocket->is_linked()) { - operation->set_canvas_input_index(2); - } - else { - operation->set_canvas_input_index(3); - } - converter.add_operation(operation); - - converter.map_input_socket(input_rsocket, operation->get_input_socket(0)); - converter.map_input_socket(input_gsocket, operation->get_input_socket(1)); - converter.map_input_socket(input_bsocket, operation->get_input_socket(2)); - converter.map_input_socket(input_asocket, operation->get_input_socket(3)); - - NodeOperation *color_conv = get_color_converter(context); - if (color_conv) { - converter.add_operation(color_conv); - - converter.add_link(operation->get_output_socket(), color_conv->get_input_socket(0)); - converter.map_output_socket(output_socket, color_conv->get_output_socket()); - } - else { - converter.map_output_socket(output_socket, operation->get_output_socket()); - } -} - -NodeOperation *CombineRGBANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return nullptr; /* no conversion needed */ -} - -NodeOperation *CombineHSVANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return new ConvertHSVToRGBOperation(); -} - -NodeOperation *CombineYCCANode::get_color_converter(const CompositorContext & /*context*/) const -{ - ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation(); - const bNode *editor_node = this->get_bnode(); - operation->set_mode(editor_node->custom1); - return operation; -} - -NodeOperation *CombineYUVANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return new ConvertYUVToRGBOperation(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.h b/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.h deleted file mode 100644 index c9b1926b30e..00000000000 --- a/source/blender/compositor/nodes/COM_CombineColorNodeLegacy.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -class CombineColorNodeLegacy : public Node { - public: - CombineColorNodeLegacy(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - protected: - virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0; -}; - -class CombineRGBANode : public CombineColorNodeLegacy { - public: - CombineRGBANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class CombineHSVANode : public CombineColorNodeLegacy { - public: - CombineHSVANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class CombineYCCANode : public CombineColorNodeLegacy { - public: - CombineYCCANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class CombineYUVANode : public CombineColorNodeLegacy { - public: - CombineYUVANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.cc b/source/blender/compositor/nodes/COM_CombineXYZNode.cc deleted file mode 100644 index 6306bec80ec..00000000000 --- a/source/blender/compositor/nodes/COM_CombineXYZNode.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CombineXYZNode.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -CombineXYZNode::CombineXYZNode(bNode *editor_node) : Node(editor_node) {} - -void CombineXYZNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_x_socket = this->get_input_socket(0); - NodeInput *input_y_socket = this->get_input_socket(1); - NodeInput *input_z_socket = this->get_input_socket(2); - NodeOutput *output_socket = this->get_output_socket(0); - - CombineChannelsOperation *operation = new CombineChannelsOperation(); - if (input_x_socket->is_linked()) { - operation->set_canvas_input_index(0); - } - else if (input_y_socket->is_linked()) { - operation->set_canvas_input_index(1); - } - else { - operation->set_canvas_input_index(2); - } - converter.add_operation(operation); - - converter.map_input_socket(input_x_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_y_socket, operation->get_input_socket(1)); - converter.map_input_socket(input_z_socket, operation->get_input_socket(2)); - converter.map_output_socket(output_socket, operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.h b/source/blender/compositor/nodes/COM_CombineXYZNode.h deleted file mode 100644 index 241158f677a..00000000000 --- a/source/blender/compositor/nodes/COM_CombineXYZNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SeparateXYZNode - * \ingroup Node - */ -class CombineXYZNode : public Node { - public: - CombineXYZNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cc b/source/blender/compositor/nodes/COM_CompositorNode.cc deleted file mode 100644 index 0087667f7f5..00000000000 --- a/source/blender/compositor/nodes/COM_CompositorNode.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CompositorNode.h" -#include "COM_CompositorOperation.h" - -namespace blender::compositor { - -CompositorNode::CompositorNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void CompositorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - bool is_active = ((editor_node->flag & NODE_DO_OUTPUT_RECALC) || context.is_rendering()) && - (editor_node->flag & NODE_DO_OUTPUT); - bool ignore_alpha = (editor_node->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0; - - NodeInput *image_socket = this->get_input_socket(0); - NodeInput *alpha_socket = this->get_input_socket(1); - - CompositorOperation *compositor_operation = new CompositorOperation(); - compositor_operation->set_scene(context.get_scene()); - compositor_operation->set_scene_name(context.get_scene()->id.name); - compositor_operation->set_render_data(context.get_render_data()); - compositor_operation->set_view_name(context.get_view_name()); - compositor_operation->set_bnodetree(context.get_bnodetree()); - /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */ - compositor_operation->set_use_alpha_input(ignore_alpha || alpha_socket->is_linked()); - compositor_operation->set_active(is_active); - - converter.add_operation(compositor_operation); - converter.map_input_socket(image_socket, compositor_operation->get_input_socket(0)); - /* only use alpha link if "use alpha" is enabled */ - if (ignore_alpha) { - converter.add_input_value(compositor_operation->get_input_socket(1), 1.0f); - } - else { - converter.map_input_socket(alpha_socket, compositor_operation->get_input_socket(1)); - } - - converter.add_node_input_preview(image_socket); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h deleted file mode 100644 index 09ff1c71fd9..00000000000 --- a/source/blender/compositor/nodes/COM_CompositorNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief CompositorNode - * \ingroup Node - */ -class CompositorNode : public Node { - public: - CompositorNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cc b/source/blender/compositor/nodes/COM_ConvertAlphaNode.cc deleted file mode 100644 index ddfdeeaafd6..00000000000 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvertAlphaNode.h" -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -void ConvertAlphaNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeOperation *operation = nullptr; - const bNode *node = this->get_bnode(); - - /* Value hardcoded in `rna_nodetree.cc`. */ - if (node->custom1 == 1) { - operation = new ConvertPremulToStraightOperation(); - } - else { - operation = new ConvertStraightToPremulOperation(); - } - - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h deleted file mode 100644 index d8389b63f1d..00000000000 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ConvertAlphaNode - * \ingroup Node - */ -class ConvertAlphaNode : public Node { - public: - ConvertAlphaNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc deleted file mode 100644 index d1cf6a41b53..00000000000 --- a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvertColorSpaceNode.h" - -#include "BKE_node.hh" - -#include "BLI_utildefines.h" - -#include "COM_ConvertColorSpaceOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_ExecutionSystem.h" -#include "COM_ImageOperation.h" -#include "COM_MultilayerImageOperation.h" - -#include "CLG_log.h" - -static CLG_LogRef LOG = {"compositor"}; - -namespace blender::compositor { - -ConvertColorSpaceNode::ConvertColorSpaceNode(bNode *editorNode) : Node(editorNode) -{ - /* pass */ -} - -void ConvertColorSpaceNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *b_node = get_bnode(); - - NodeInput *inputSocketImage = this->get_input_socket(0); - NodeOutput *outputSocketImage = this->get_output_socket(0); - - NodeConvertColorSpace *settings = static_cast(b_node->storage); - - if (!performs_conversion(*settings)) { - converter.map_output_socket(get_output_socket(0), - converter.add_input_proxy(get_input_socket(0), false)); - return; - } - - ConvertColorSpaceOperation *operation = new ConvertColorSpaceOperation(); - operation->set_settings((NodeConvertColorSpace *)b_node->storage); - converter.add_operation(operation); - - converter.map_input_socket(inputSocketImage, operation->get_input_socket(0)); - converter.map_output_socket(outputSocketImage, operation->get_output_socket()); -} - -bool ConvertColorSpaceNode::performs_conversion(NodeConvertColorSpace &settings) const -{ - const bNode *b_node = get_bnode(); - - if (IMB_colormanagement_space_name_is_data(settings.from_color_space)) { - CLOG_INFO(&LOG, - 2, - "Color space conversion bypassed for node: %s. From color space is data: %s.", - b_node->name, - settings.from_color_space); - return false; - } - - if (IMB_colormanagement_space_name_is_data(settings.to_color_space)) { - CLOG_INFO(&LOG, - 2, - "Color space conversion bypassed for node: %s. To color space is data: %s.", - b_node->name, - settings.to_color_space); - return false; - } - - if (STREQLEN( - settings.from_color_space, settings.to_color_space, sizeof(settings.from_color_space))) - { - CLOG_INFO(&LOG, - 2, - "Color space conversion bypassed for node: %s. To and from are the same: %s.", - b_node->name, - settings.from_color_space); - return false; - } - return true; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h deleted file mode 100644 index 0f9dc8f68f1..00000000000 --- a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "COM_defines.h" -#include "DNA_image_types.h" -#include "DNA_node_types.h" - -#include "RE_engine.h" -#include "RE_pipeline.h" - -namespace blender::compositor { - -/** - * \brief ImageNode - * \ingroup Node - */ -class ConvertColorSpaceNode : public Node { - public: - ConvertColorSpaceNode(bNode *editorNode); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - private: - /** \brief check if the given settings changes color space. */ - bool performs_conversion(NodeConvertColorSpace &settings) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.cc b/source/blender/compositor/nodes/COM_CornerPinNode.cc deleted file mode 100644 index 66d9be04f3b..00000000000 --- a/source/blender/compositor/nodes/COM_CornerPinNode.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CornerPinNode.h" - -#include "COM_PlaneCornerPinOperation.h" -#include "COM_SMAAOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -CornerPinNode::CornerPinNode(bNode *editor_node) : Node(editor_node) {} - -void CornerPinNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - PlaneCornerPinMaskOperation *plane_mask_operation = new PlaneCornerPinMaskOperation(); - converter.add_operation(plane_mask_operation); - - SMAAOperation *smaa_operation = new SMAAOperation(); - converter.add_operation(smaa_operation); - - converter.add_link(plane_mask_operation->get_output_socket(), - smaa_operation->get_input_socket(0)); - - converter.map_output_socket(this->get_output_socket(1), smaa_operation->get_output_socket()); - - PlaneCornerPinWarpImageOperation *warp_image_operation = new PlaneCornerPinWarpImageOperation(); - converter.add_operation(warp_image_operation); - converter.map_input_socket(this->get_input_socket(0), warp_image_operation->get_input_socket(0)); - - /* NOTE: socket order differs between UI node and operations: - * bNode uses intuitive order following top-down layout: - * upper-left, upper-right, lower-left, lower-right - * Operations use same order as the tracking blenkernel functions expect: - * lower-left, lower-right, upper-right, upper-left - */ - const int node_corner_index[4] = {3, 4, 2, 1}; - for (int i = 0; i < 4; i++) { - NodeInput *corner_input = get_input_socket(node_corner_index[i]); - converter.map_input_socket(corner_input, warp_image_operation->get_input_socket(i + 1)); - converter.map_input_socket(corner_input, plane_mask_operation->get_input_socket(i)); - } - - SetAlphaMultiplyOperation *set_alpha_operation = new SetAlphaMultiplyOperation(); - converter.add_operation(set_alpha_operation); - converter.add_link(warp_image_operation->get_output_socket(), - set_alpha_operation->get_input_socket(0)); - converter.add_link(smaa_operation->get_output_socket(), - set_alpha_operation->get_input_socket(1)); - converter.map_output_socket(this->get_output_socket(0), - set_alpha_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.h b/source/blender/compositor/nodes/COM_CornerPinNode.h deleted file mode 100644 index 6e2b8cf48cf..00000000000 --- a/source/blender/compositor/nodes/COM_CornerPinNode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief CornerPinNode - * \ingroup Node - */ -class CornerPinNode : public Node { - public: - CornerPinNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CropNode.cc b/source/blender/compositor/nodes/COM_CropNode.cc deleted file mode 100644 index a8590e6ce32..00000000000 --- a/source/blender/compositor/nodes/COM_CropNode.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CropNode.h" -#include "COM_CropOperation.h" - -namespace blender::compositor { - -CropNode::CropNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void CropNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = get_bnode(); - NodeTwoXYs *crop_settings = (NodeTwoXYs *)node->storage; - bool relative = bool(node->custom2); - bool crop_image = bool(node->custom1); - CropBaseOperation *operation; - if (crop_image) { - operation = new CropImageOperation(); - } - else { - operation = new CropOperation(); - } - operation->set_crop_settings(crop_settings); - operation->set_relative(relative); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h deleted file mode 100644 index be0c2af2c25..00000000000 --- a/source/blender/compositor/nodes/COM_CropNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief CropNode - * \ingroup Node - */ -class CropNode : public Node { - public: - CropNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cc b/source/blender/compositor/nodes/COM_CryptomatteNode.cc deleted file mode 100644 index ea9546a8e34..00000000000 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cc +++ /dev/null @@ -1,258 +0,0 @@ -/* SPDX-FileCopyrightText: 2018 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_string.h" - -#include "BKE_node.hh" - -#include "NOD_composite.hh" - -#include "COM_ConvertOperation.h" -#include "COM_CryptomatteNode.h" -#include "COM_MultilayerImageOperation.h" -#include "COM_RenderLayersProg.h" -#include "COM_SetAlphaMultiplyOperation.h" -#include "COM_SetColorOperation.h" - -namespace blender::compositor { - -/* -------------------------------------------------------------------- */ -/** \name Cryptomatte Base - * \{ */ - -void CryptomatteBaseNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeOutput *output_image_socket = this->get_output_socket(0); - - const bNode *node = this->get_bnode(); - const NodeCryptomatte *cryptomatte_settings = static_cast( - node->storage); - - CryptomatteOperation *cryptomatte_operation = create_cryptomatte_operation( - converter, context, *node, cryptomatte_settings); - converter.add_operation(cryptomatte_operation); - - NodeOutput *output_matte_socket = this->get_output_socket(1); - SeparateChannelOperation *extract_mask_operation = new SeparateChannelOperation; - extract_mask_operation->set_channel(3); - converter.add_operation(extract_mask_operation); - converter.add_link(cryptomatte_operation->get_output_socket(0), - extract_mask_operation->get_input_socket(0)); - converter.map_output_socket(output_matte_socket, extract_mask_operation->get_output_socket(0)); - - NodeInput *input_image_socket = this->get_input_socket(0); - SetAlphaMultiplyOperation *apply_mask_operation = new SetAlphaMultiplyOperation(); - converter.map_input_socket(input_image_socket, apply_mask_operation->get_input_socket(0)); - converter.add_operation(apply_mask_operation); - converter.add_link(extract_mask_operation->get_output_socket(0), - apply_mask_operation->get_input_socket(1)); - converter.map_output_socket(output_image_socket, apply_mask_operation->get_output_socket(0)); - - NodeOutput *output_pick_socket = this->get_output_socket(2); - CryptomattePickOperation *extract_pick_operation = new CryptomattePickOperation(); - converter.add_operation(extract_pick_operation); - converter.add_input_value(extract_pick_operation->get_input_socket(1), 1.0f); - converter.add_link(cryptomatte_operation->get_output_socket(0), - extract_pick_operation->get_input_socket(0)); - converter.map_output_socket(output_pick_socket, extract_pick_operation->get_output_socket(0)); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Cryptomatte V2 - * \{ */ - -static std::string prefix_from_node(const bNode &node) -{ - char prefix[MAX_NAME]; - ntreeCompositCryptomatteLayerPrefix(&node, prefix, sizeof(prefix)); - return std::string(prefix, BLI_strnlen(prefix, sizeof(prefix))); -} - -static std::string combined_layer_pass_name(RenderLayer *render_layer, RenderPass *render_pass) -{ - if (render_layer->name[0] == '\0') { - return std::string(render_pass->name, - BLI_strnlen(render_pass->name, sizeof(render_pass->name))); - } - - std::string combined_name = - blender::StringRef(render_layer->name, - BLI_strnlen(render_layer->name, sizeof(render_layer->name))) + - "." + - blender::StringRef(render_pass->name, - BLI_strnlen(render_pass->name, sizeof(render_pass->name))); - return combined_name; -} - -void CryptomatteNode::input_operations_from_render_source( - const CompositorContext &context, - const bNode &node, - Vector &r_input_operations) -{ - Scene *scene = (Scene *)node.id; - if (!scene) { - return; - } - - BLI_assert(GS(scene->id.name) == ID_SCE); - Render *render = RE_GetSceneRender(scene); - RenderResult *render_result = render ? RE_AcquireResultRead(render) : nullptr; - - if (!render_result) { - if (render) { - RE_ReleaseResult(render); - } - return; - } - - short view_layer_id = 0; - const std::string prefix = prefix_from_node(node); - LISTBASE_FOREACH_INDEX (ViewLayer *, view_layer, &scene->view_layers, view_layer_id) { - RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name); - if (render_layer) { - LISTBASE_FOREACH (RenderPass *, render_pass, &render_layer->passes) { - if (context.has_explicit_view() && !STREQ(render_pass->view, context.get_view_name())) { - continue; - } - - const std::string combined_name = combined_layer_pass_name(render_layer, render_pass); - if (combined_name != prefix && blender::StringRef(combined_name).startswith(prefix)) { - RenderLayersProg *op = new RenderLayersProg( - render_pass->name, DataType::Color, render_pass->channels); - op->set_scene(scene); - op->set_layer_id(view_layer_id); - op->set_render_data(context.get_render_data()); - op->set_view_name(context.get_view_name()); - r_input_operations.append(op); - } - } - } - } - RE_ReleaseResult(render); -} - -void CryptomatteNode::input_operations_from_image_source( - const CompositorContext &context, - const bNode &node, - Vector &r_input_operations) -{ - NodeCryptomatte *cryptomatte_settings = (NodeCryptomatte *)node.storage; - Image *image = (Image *)node.id; - if (!image) { - return; - } - - BLI_assert(GS(image->id.name) == ID_IM); - if (image->type != IMA_TYPE_MULTILAYER) { - return; - } - - ImageUser *iuser = &cryptomatte_settings->iuser; - BKE_image_user_frame_calc(image, iuser, context.get_framenumber()); - ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, nullptr); - - if (image->rr) { - const std::string prefix = prefix_from_node(node); - int layer_index; - LISTBASE_FOREACH_INDEX (RenderLayer *, render_layer, &image->rr->layers, layer_index) { - if (!blender::StringRef(prefix).startswith(blender::StringRef( - render_layer->name, BLI_strnlen(render_layer->name, sizeof(render_layer->name))))) - { - continue; - } - LISTBASE_FOREACH (RenderPass *, render_pass, &render_layer->passes) { - const std::string combined_name = combined_layer_pass_name(render_layer, render_pass); - if (combined_name != prefix && blender::StringRef(combined_name).startswith(prefix)) { - MultilayerColorOperation *op = new MultilayerColorOperation(); - iuser->layer = layer_index; - op->set_image(image); - op->set_image_user(*iuser); - op->set_framenumber(context.get_framenumber()); - op->set_render_data(context.get_render_data()); - op->set_view_name(context.get_view_name()); - op->set_layer_name(render_layer->name); - op->set_pass_name(render_pass->name); - r_input_operations.append(op); - } - } - break; - } - } - BKE_image_release_ibuf(image, ibuf, nullptr); -} - -Vector CryptomatteNode::create_input_operations(const CompositorContext &context, - const bNode &node) -{ - Vector input_operations; - switch (node.custom1) { - case CMP_NODE_CRYPTOMATTE_SOURCE_RENDER: - input_operations_from_render_source(context, node, input_operations); - break; - case CMP_NODE_CRYPTOMATTE_SOURCE_IMAGE: - input_operations_from_image_source(context, node, input_operations); - break; - } - - if (input_operations.is_empty()) { - SetColorOperation *op = new SetColorOperation(); - op->set_channel1(0.0f); - op->set_channel2(1.0f); - op->set_channel3(0.0f); - op->set_channel4(0.0f); - input_operations.append(op); - } - return input_operations; -} -CryptomatteOperation *CryptomatteNode::create_cryptomatte_operation( - NodeConverter &converter, - const CompositorContext &context, - const bNode &node, - const NodeCryptomatte *cryptomatte_settings) const -{ - Vector input_operations = create_input_operations(context, node); - CryptomatteOperation *operation = new CryptomatteOperation(input_operations.size()); - LISTBASE_FOREACH (CryptomatteEntry *, cryptomatte_entry, &cryptomatte_settings->entries) { - operation->add_object_index(cryptomatte_entry->encoded_hash); - } - for (int i = 0; i < input_operations.size(); ++i) { - converter.add_operation(input_operations[i]); - converter.add_link(input_operations[i]->get_output_socket(), operation->get_input_socket(i)); - } - return operation; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Cryptomatte Legacy - * \{ */ - -CryptomatteOperation *CryptomatteLegacyNode::create_cryptomatte_operation( - NodeConverter &converter, - const CompositorContext & /*context*/, - const bNode & /*node*/, - const NodeCryptomatte *cryptomatte_settings) const -{ - const int num_inputs = inputs_.size() - 1; - CryptomatteOperation *operation = new CryptomatteOperation(num_inputs); - if (cryptomatte_settings) { - LISTBASE_FOREACH (CryptomatteEntry *, cryptomatte_entry, &cryptomatte_settings->entries) { - operation->add_object_index(cryptomatte_entry->encoded_hash); - } - } - - for (int i = 0; i < num_inputs; i++) { - converter.map_input_socket(this->get_input_socket(i + 1), operation->get_input_socket(i)); - } - - return operation; -} - -/** \} */ - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h deleted file mode 100644 index fd1cdf8836c..00000000000 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-FileCopyrightText: 2018 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_string_ref.hh" -#include "BLI_vector.hh" - -#include "COM_CryptomatteOperation.h" -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief CryptomatteNode - * \ingroup Node - */ -class CryptomatteBaseNode : public Node { - protected: - CryptomatteBaseNode(bNode *editor_node) : Node(editor_node) - { - /* pass */ - } - - public: - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - protected: - virtual CryptomatteOperation *create_cryptomatte_operation( - NodeConverter &converter, - const CompositorContext &context, - const bNode &node, - const NodeCryptomatte *cryptomatte_settings) const = 0; -}; - -class CryptomatteNode : public CryptomatteBaseNode { - public: - CryptomatteNode(bNode *editor_node) : CryptomatteBaseNode(editor_node) - { - /* pass */ - } - - protected: - CryptomatteOperation *create_cryptomatte_operation( - NodeConverter &converter, - const CompositorContext &context, - const bNode &node, - const NodeCryptomatte *cryptomatte_settings) const override; - - private: - static Vector create_input_operations(const CompositorContext &context, - const bNode &node); - static void input_operations_from_render_source(const CompositorContext &context, - const bNode &node, - Vector &r_input_operations); - static void input_operations_from_image_source(const CompositorContext &context, - const bNode &node, - Vector &r_input_operations); -}; - -class CryptomatteLegacyNode : public CryptomatteBaseNode { - public: - CryptomatteLegacyNode(bNode *editor_node) : CryptomatteBaseNode(editor_node) - { - /* pass */ - } - - protected: - CryptomatteOperation *create_cryptomatte_operation( - NodeConverter &converter, - const CompositorContext &context, - const bNode &node, - const NodeCryptomatte *cryptomatte_settings) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cc b/source/blender/compositor/nodes/COM_DefocusNode.cc deleted file mode 100644 index 7ee1ef3e599..00000000000 --- a/source/blender/compositor/nodes/COM_DefocusNode.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "DNA_scene_types.h" - -#include "BKE_camera.h" - -#include "COM_BokehImageOperation.h" -#include "COM_ConvertDepthToRadiusOperation.h" -#include "COM_DefocusNode.h" -#include "COM_FastGaussianBlurOperation.h" -#include "COM_GammaCorrectOperation.h" -#include "COM_MathBaseOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_VariableSizeBokehBlurOperation.h" - -namespace blender::compositor { - -DefocusNode::DefocusNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DefocusNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *node = this->get_bnode(); - const NodeDefocus *data = (const NodeDefocus *)node->storage; - - NodeOperation *radius_operation; - if (data->no_zbuf) { - MathMultiplyOperation *multiply = new MathMultiplyOperation(); - SetValueOperation *multiplier = new SetValueOperation(); - multiplier->set_value(data->scale); - SetValueOperation *max_radius = new SetValueOperation(); - max_radius->set_value(data->maxblur); - MathMinimumOperation *minimize = new MathMinimumOperation(); - - converter.add_operation(multiply); - converter.add_operation(multiplier); - converter.add_operation(max_radius); - converter.add_operation(minimize); - - converter.map_input_socket(get_input_socket(1), multiply->get_input_socket(0)); - converter.add_link(multiplier->get_output_socket(), multiply->get_input_socket(1)); - converter.add_link(multiply->get_output_socket(), minimize->get_input_socket(0)); - converter.add_link(max_radius->get_output_socket(), minimize->get_input_socket(1)); - - radius_operation = minimize; - } - else { - ConvertDepthToRadiusOperation *radius_op = new ConvertDepthToRadiusOperation(); - radius_op->set_data(data); - radius_op->set_scene(get_scene(context)); - converter.add_operation(radius_op); - converter.map_input_socket(get_input_socket(1), radius_op->get_input_socket(0)); - converter.map_input_socket(get_input_socket(0), radius_op->get_input_socket(1)); - - GaussianXBlurOperation *blur_x_operation = new GaussianXBlurOperation(); - converter.add_operation(blur_x_operation); - converter.add_link(radius_op->get_output_socket(), blur_x_operation->get_input_socket(0)); - - GaussianYBlurOperation *blur_y_operation = new GaussianYBlurOperation(); - converter.add_operation(blur_y_operation); - converter.add_link(blur_x_operation->get_output_socket(), - blur_y_operation->get_input_socket(0)); - - MathMinimumOperation *minimum_operation = new MathMinimumOperation(); - converter.add_operation(minimum_operation); - converter.add_link(blur_y_operation->get_output_socket(), - minimum_operation->get_input_socket(0)); - converter.add_link(radius_op->get_output_socket(), minimum_operation->get_input_socket(1)); - - radius_op->set_blur_x_operation(blur_x_operation); - radius_op->set_blur_y_operation(blur_y_operation); - - radius_operation = minimum_operation; - } - - NodeBokehImage *bokehdata = new NodeBokehImage(); - bokehdata->angle = data->rotation; - bokehdata->rounding = 0.0f; - bokehdata->flaps = data->bktype; - if (data->bktype < 3) { - bokehdata->flaps = 5; - bokehdata->rounding = 1.0f; - } - bokehdata->catadioptric = 0.0f; - bokehdata->lensshift = 0.0f; - - BokehImageOperation *bokeh = new BokehImageOperation(); - bokeh->set_data(bokehdata); - bokeh->set_resolution(math::ceil(data->maxblur) * 2 + 1); - bokeh->delete_data_on_finish(); - converter.add_operation(bokeh); - - SetValueOperation *bounding_box_operation = new SetValueOperation(); - bounding_box_operation->set_value(1.0f); - converter.add_operation(bounding_box_operation); - - VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); - operation->set_max_blur(data->maxblur); - operation->set_threshold(0.0f); - converter.add_operation(operation); - - converter.add_link(bokeh->get_output_socket(), operation->get_input_socket(1)); - converter.add_link(radius_operation->get_output_socket(), operation->get_input_socket(2)); - converter.add_link(bounding_box_operation->get_output_socket(), operation->get_input_socket(3)); - - if (data->gamco) { - GammaCorrectOperation *correct = new GammaCorrectOperation(); - converter.add_operation(correct); - GammaUncorrectOperation *inverse = new GammaUncorrectOperation(); - converter.add_operation(inverse); - - converter.map_input_socket(get_input_socket(0), correct->get_input_socket(0)); - converter.add_link(correct->get_output_socket(), operation->get_input_socket(0)); - converter.add_link(operation->get_output_socket(), inverse->get_input_socket(0)); - converter.map_output_socket(get_output_socket(), inverse->get_output_socket()); - } - else { - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(), operation->get_output_socket()); - } -} - -const Scene *DefocusNode::get_scene(const CompositorContext &context) const -{ - return get_bnode()->id ? reinterpret_cast(get_bnode()->id) : context.get_scene(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h deleted file mode 100644 index 98dfe47ed4e..00000000000 --- a/source/blender/compositor/nodes/COM_DefocusNode.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "DNA_scene_types.h" - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DefocusNode - * \ingroup Node - */ -class DefocusNode : public Node { - public: - DefocusNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - const Scene *get_scene(const CompositorContext &context) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.cc b/source/blender/compositor/nodes/COM_DenoiseNode.cc deleted file mode 100644 index 345390789e4..00000000000 --- a/source/blender/compositor/nodes/COM_DenoiseNode.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2019 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "COM_DenoiseNode.h" -#include "COM_DenoiseOperation.h" - -namespace blender::compositor { - -DenoiseNode::DenoiseNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DenoiseNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - if (!COM_is_denoise_supported()) { - converter.map_output_socket(get_output_socket(0), - converter.add_input_proxy(get_input_socket(0), false)); - return; - } - - const bNode *node = this->get_bnode(); - const NodeDenoise *denoise = (const NodeDenoise *)node->storage; - - DenoiseOperation *operation = new DenoiseOperation(); - converter.add_operation(operation); - operation->set_denoise_settings(denoise); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - if (denoise && denoise->prefilter == CMP_NODE_DENOISE_PREFILTER_ACCURATE) { - { - DenoisePrefilterOperation *normal_prefilter = new DenoisePrefilterOperation( - DataType::Vector); - normal_prefilter->set_image_name("normal"); - converter.add_operation(normal_prefilter); - converter.map_input_socket(get_input_socket(1), normal_prefilter->get_input_socket(0)); - converter.add_link(normal_prefilter->get_output_socket(), operation->get_input_socket(1)); - } - { - DenoisePrefilterOperation *albedo_prefilter = new DenoisePrefilterOperation(DataType::Color); - albedo_prefilter->set_image_name("albedo"); - converter.add_operation(albedo_prefilter); - converter.map_input_socket(get_input_socket(2), albedo_prefilter->get_input_socket(0)); - converter.add_link(albedo_prefilter->get_output_socket(), operation->get_input_socket(2)); - } - } - else { - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - } - - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DenoiseNode.h b/source/blender/compositor/nodes/COM_DenoiseNode.h deleted file mode 100644 index a20a7f0f17e..00000000000 --- a/source/blender/compositor/nodes/COM_DenoiseNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2019 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DenoiseNode - * \ingroup Node - */ -class DenoiseNode : public Node { - public: - DenoiseNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.cc b/source/blender/compositor/nodes/COM_DespeckleNode.cc deleted file mode 100644 index 6761309932c..00000000000 --- a/source/blender/compositor/nodes/COM_DespeckleNode.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DespeckleNode.h" -#include "COM_DespeckleOperation.h" - -namespace blender::compositor { - -DespeckleNode::DespeckleNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DespeckleNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_image_socket = this->get_input_socket(1); - NodeOutput *output_socket = this->get_output_socket(0); - - DespeckleOperation *operation = new DespeckleOperation(); - operation->set_threshold(editor_node->custom3); - operation->set_threshold_neighbor(editor_node->custom4); - converter.add_operation(operation); - - converter.map_input_socket(input_image_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_socket, operation->get_input_socket(1)); - converter.map_output_socket(output_socket, operation->get_output_socket()); - - converter.add_preview(operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.h b/source/blender/compositor/nodes/COM_DespeckleNode.h deleted file mode 100644 index 14f6a819f17..00000000000 --- a/source/blender/compositor/nodes/COM_DespeckleNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DespeckleNode - * \ingroup Node - */ -class DespeckleNode : public Node { - public: - DespeckleNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cc b/source/blender/compositor/nodes/COM_DifferenceMatteNode.cc deleted file mode 100644 index 32b10a9e964..00000000000 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DifferenceMatteNode.h" -#include "COM_DifferenceMatteOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -DifferenceMatteNode::DifferenceMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DifferenceMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_socket2 = this->get_input_socket(1); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - const bNode *editor_node = this->get_bnode(); - - DifferenceMatteOperation *operation_set = new DifferenceMatteOperation(); - operation_set->set_settings((NodeChroma *)editor_node->storage); - converter.add_operation(operation_set); - - converter.map_input_socket(input_socket, operation_set->get_input_socket(0)); - converter.map_input_socket(input_socket2, operation_set->get_input_socket(1)); - converter.map_output_socket(output_socket_matte, operation_set->get_output_socket(0)); - - SetAlphaMultiplyOperation *operation = new SetAlphaMultiplyOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.add_link(operation_set->get_output_socket(), operation->get_input_socket(1)); - converter.map_output_socket(output_socket_image, operation->get_output_socket()); - - converter.add_preview(operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h deleted file mode 100644 index 98284e4f948..00000000000 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DifferenceMatteNode - * \ingroup Node - */ -class DifferenceMatteNode : public Node { - public: - DifferenceMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cc b/source/blender/compositor/nodes/COM_DilateErodeNode.cc deleted file mode 100644 index 6597438ef18..00000000000 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DilateErodeNode.h" -#include "COM_DilateErodeOperation.h" -#include "COM_GaussianAlphaBlurBaseOperation.h" -#include "COM_SMAAOperation.h" - -namespace blender::compositor { - -DilateErodeNode::DilateErodeNode(bNode *editor_node) : Node(editor_node) -{ - /* initialize node data */ - NodeBlurData *data = &alpha_blur_; - memset(data, 0, sizeof(NodeBlurData)); - data->filtertype = R_FILTER_GAUSS; - - if (editor_node->custom2 > 0) { - data->sizex = data->sizey = editor_node->custom2; - } - else { - data->sizex = data->sizey = -editor_node->custom2; - } -} - -void DilateErodeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - if (editor_node->custom1 == CMP_NODE_DILATE_ERODE_DISTANCE_THRESHOLD) { - DilateErodeThresholdOperation *operation = new DilateErodeThresholdOperation(); - operation->set_distance(editor_node->custom2); - operation->set_inset(editor_node->custom3); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - - if (editor_node->custom3 < 2.0f) { - SMAAOperation *smaa_operation = new SMAAOperation(); - converter.add_operation(smaa_operation); - converter.add_link(operation->get_output_socket(), smaa_operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), smaa_operation->get_output_socket()); - } - else { - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - } - else if (editor_node->custom1 == CMP_NODE_DILATE_ERODE_DISTANCE) { - if (editor_node->custom2 > 0) { - DilateDistanceOperation *operation = new DilateDistanceOperation(); - operation->set_distance(editor_node->custom2); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - else { - ErodeDistanceOperation *operation = new ErodeDistanceOperation(); - operation->set_distance(-editor_node->custom2); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - } - else if (editor_node->custom1 == CMP_NODE_DILATE_ERODE_DISTANCE_FEATHER) { - GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation(); - operationx->set_data(&alpha_blur_); - operationx->set_falloff(PROP_SMOOTH); - converter.add_operation(operationx); - - converter.map_input_socket(get_input_socket(0), operationx->get_input_socket(0)); - // converter.map_input_socket(get_input_socket(1), operationx->get_input_socket(1)); // no size - // input yet - - GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation(); - operationy->set_data(&alpha_blur_); - operationy->set_falloff(PROP_SMOOTH); - converter.add_operation(operationy); - - converter.add_link(operationx->get_output_socket(), operationy->get_input_socket(0)); - // converter.map_input_socket(get_input_socket(1), operationy->get_input_socket(1)); // no size - // input yet - converter.map_output_socket(get_output_socket(0), operationy->get_output_socket()); - - converter.add_preview(operationy->get_output_socket()); - - /* TODO? */ - /* see gaussian blue node for original usage */ -#if 0 - if (!connected_size_socket) { - operationx->set_size(size); - operationy->set_size(size); - } -#else - operationx->set_size(1.0f); - operationy->set_size(1.0f); -#endif - operationx->set_subtract(editor_node->custom2 < 0); - operationy->set_subtract(editor_node->custom2 < 0); - - if (editor_node->storage) { - NodeDilateErode *data_storage = (NodeDilateErode *)editor_node->storage; - operationx->set_falloff(data_storage->falloff); - operationy->set_falloff(data_storage->falloff); - } - } - else { - if (editor_node->custom2 > 0) { - DilateStepOperation *operation = new DilateStepOperation(); - operation->set_iterations(editor_node->custom2); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - else { - ErodeStepOperation *operation = new ErodeStepOperation(); - operation->set_iterations(-editor_node->custom2); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h deleted file mode 100644 index bf73a13e91b..00000000000 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DilateErodeNode - * \ingroup Node - */ -class DilateErodeNode : public Node { - /** only used for blurring alpha, since the dilate/erode node doesn't have this. */ - NodeBlurData alpha_blur_; - - public: - DilateErodeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cc b/source/blender/compositor/nodes/COM_DirectionalBlurNode.cc deleted file mode 100644 index 645944c0ce9..00000000000 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DirectionalBlurNode.h" -#include "COM_DirectionalBlurOperation.h" - -namespace blender::compositor { - -DirectionalBlurNode::DirectionalBlurNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DirectionalBlurNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const NodeDBlurData *data = (const NodeDBlurData *)this->get_bnode()->storage; - DirectionalBlurOperation *operation = new DirectionalBlurOperation(); - operation->set_data(data); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h deleted file mode 100644 index 824f678ed65..00000000000 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DirectionalBlurNode - * \ingroup Node - */ -class DirectionalBlurNode : public Node { - public: - DirectionalBlurNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.cc b/source/blender/compositor/nodes/COM_DisplaceNode.cc deleted file mode 100644 index ddf228726eb..00000000000 --- a/source/blender/compositor/nodes/COM_DisplaceNode.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DisplaceNode.h" -#include "COM_DisplaceOperation.h" - -namespace blender::compositor { - -DisplaceNode::DisplaceNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DisplaceNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeOperation *operation = new DisplaceOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h deleted file mode 100644 index e59478b6b3a..00000000000 --- a/source/blender/compositor/nodes/COM_DisplaceNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DisplaceNode - * \ingroup Node - */ -class DisplaceNode : public Node { - public: - DisplaceNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.cc b/source/blender/compositor/nodes/COM_DistanceMatteNode.cc deleted file mode 100644 index eaf2bad0722..00000000000 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DistanceMatteNode.h" -#include "COM_ConvertOperation.h" -#include "COM_DistanceYCCMatteOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -DistanceMatteNode::DistanceMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DistanceMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editorsnode = this->get_bnode(); - const NodeChroma *storage = (const NodeChroma *)editorsnode->storage; - - NodeInput *input_socket_image = this->get_input_socket(0); - NodeInput *input_socket_key = this->get_input_socket(1); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - - SetAlphaMultiplyOperation *operation_alpha = new SetAlphaMultiplyOperation(); - converter.add_operation(operation_alpha); - - /* work in RGB color space */ - NodeOperation *operation; - if (storage->channel == 1) { - DistanceRGBMatteOperation *matte = new DistanceRGBMatteOperation(); - matte->set_settings(storage); - converter.add_operation(matte); - - converter.map_input_socket(input_socket_image, matte->get_input_socket(0)); - converter.map_input_socket(input_socket_image, operation_alpha->get_input_socket(0)); - - converter.map_input_socket(input_socket_key, matte->get_input_socket(1)); - - operation = matte; - } - /* work in YCbCr color space */ - else { - DistanceYCCMatteOperation *matte = new DistanceYCCMatteOperation(); - matte->set_settings(storage); - converter.add_operation(matte); - - ConvertRGBToYCCOperation *operation_yccimage = new ConvertRGBToYCCOperation(); - ConvertRGBToYCCOperation *operation_yccmatte = new ConvertRGBToYCCOperation(); - operation_yccimage->set_mode(BLI_YCC_ITU_BT709); - operation_yccmatte->set_mode(BLI_YCC_ITU_BT709); - converter.add_operation(operation_yccimage); - converter.add_operation(operation_yccmatte); - - converter.map_input_socket(input_socket_image, operation_yccimage->get_input_socket(0)); - converter.add_link(operation_yccimage->get_output_socket(), matte->get_input_socket(0)); - converter.add_link(operation_yccimage->get_output_socket(), - operation_alpha->get_input_socket(0)); - - converter.map_input_socket(input_socket_key, operation_yccmatte->get_input_socket(0)); - converter.add_link(operation_yccmatte->get_output_socket(), matte->get_input_socket(1)); - - operation = matte; - } - - converter.map_output_socket(output_socket_matte, operation->get_output_socket(0)); - converter.add_link(operation->get_output_socket(), operation_alpha->get_input_socket(1)); - - if (storage->channel != 1) { - ConvertYCCToRGBOperation *inv_convert = new ConvertYCCToRGBOperation(); - inv_convert->set_mode(BLI_YCC_ITU_BT709); - - converter.add_operation(inv_convert); - converter.add_link(operation_alpha->get_output_socket(0), inv_convert->get_input_socket(0)); - converter.map_output_socket(output_socket_image, inv_convert->get_output_socket()); - converter.add_preview(inv_convert->get_output_socket()); - } - else { - converter.map_output_socket(output_socket_image, operation_alpha->get_output_socket()); - converter.add_preview(operation_alpha->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h deleted file mode 100644 index 65b65f10900..00000000000 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DistanceMatteNode - * \ingroup Node - */ -class DistanceMatteNode : public Node { - public: - DistanceMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cc b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cc deleted file mode 100644 index fd7b9589fcb..00000000000 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DoubleEdgeMaskNode.h" -#include "COM_DoubleEdgeMaskOperation.h" - -namespace blender::compositor { - -DoubleEdgeMaskNode::DoubleEdgeMaskNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void DoubleEdgeMaskNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - DoubleEdgeMaskOperation *operation; - const bNode *bnode = this->get_bnode(); - - operation = new DoubleEdgeMaskOperation(); - operation->set_include_all_inner_edges(!bool(bnode->custom1)); - operation->set_include_edges_of_image(bool(bnode->custom2)); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h deleted file mode 100644 index bb8de21f641..00000000000 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief DoubleEdgeMaskNode - * \ingroup Node - */ -class DoubleEdgeMaskNode : public Node { - public: - DoubleEdgeMaskNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.cc b/source/blender/compositor/nodes/COM_EllipseMaskNode.cc deleted file mode 100644 index e9b263a24b0..00000000000 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_EllipseMaskNode.h" -#include "COM_EllipseMaskOperation.h" - -#include "COM_ScaleOperation.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -EllipseMaskNode::EllipseMaskNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void EllipseMaskNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - - EllipseMaskOperation *operation; - operation = new EllipseMaskOperation(); - operation->set_data((NodeEllipseMask *)this->get_bnode()->storage); - operation->set_mask_type(this->get_bnode()->custom1); - converter.add_operation(operation); - - if (input_socket->is_linked()) { - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket()); - } - else { - /* Value operation to produce original transparent image */ - SetValueOperation *value_operation = new SetValueOperation(); - value_operation->set_value(0.0f); - converter.add_operation(value_operation); - - /* Scale that image up to render resolution */ - const RenderData *rd = context.get_render_data(); - const float render_size_factor = context.get_render_percentage_as_factor(); - ScaleFixedSizeOperation *scale_operation = new ScaleFixedSizeOperation(); - - scale_operation->set_is_aspect(false); - scale_operation->set_is_crop(false); - scale_operation->set_offset(0.0f, 0.0f); - scale_operation->set_new_width(rd->xsch * render_size_factor); - scale_operation->set_new_height(rd->ysch * render_size_factor); - scale_operation->get_input_socket(0)->set_resize_mode(ResizeMode::Align); - converter.add_operation(scale_operation); - - converter.add_link(value_operation->get_output_socket(0), - scale_operation->get_input_socket(0)); - converter.add_link(scale_operation->get_output_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - } - - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h deleted file mode 100644 index 4cfefa8a643..00000000000 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief EllipseMaskNode - * \ingroup Node - */ -class EllipseMaskNode : public Node { - public: - EllipseMaskNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FileOutputNode.cc b/source/blender/compositor/nodes/COM_FileOutputNode.cc deleted file mode 100644 index 15bff0e008b..00000000000 --- a/source/blender/compositor/nodes/COM_FileOutputNode.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_FileOutputNode.h" - -#include "BLI_string.h" - -namespace blender::compositor { - -FileOutputNode::FileOutputNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -static DataType get_input_data_type(NodeInput *input) -{ - const DataType data_type = input->get_data_type(); - /* Incoming inputs to vector sockets can be 4D, so we declare them as 4-channel color inputs to - * avoid loss of fourth channel due to implicit conversion. The operation will look into the - * is_4d_vector meta data member of the input to check if it should be written as 4D or 3D, where - * the last channel will be ignored in the 3D case. */ - if (data_type == DataType::Vector) { - return DataType::Color; - } - return data_type; -} - -void FileOutputNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - for (NodeInput *input : inputs_) { - if (input->is_linked()) { - converter.add_node_input_preview(input); - break; - } - } - - if (!context.is_rendering()) { - return; - } - - Vector inputs; - for (NodeInput *input : inputs_) { - auto *storage = static_cast(input->get_bnode_socket()->storage); - inputs.append(FileOutputInput(storage, get_input_data_type(input), input->get_data_type())); - } - - auto *storage = static_cast(this->get_bnode()->storage); - auto *output_operation = new FileOutputOperation(&context, storage, inputs); - converter.add_operation(output_operation); - - for (int i = 0; i < inputs_.size(); i++) { - converter.map_input_socket(inputs_[i], output_operation->get_input_socket(i)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FileOutputNode.h b/source/blender/compositor/nodes/COM_FileOutputNode.h deleted file mode 100644 index 4dd991b24d2..00000000000 --- a/source/blender/compositor/nodes/COM_FileOutputNode.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -#include "COM_FileOutputOperation.h" - -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief FileOutputNode - * \ingroup Node - */ -class FileOutputNode : public Node { - public: - FileOutputNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FilterNode.cc b/source/blender/compositor/nodes/COM_FilterNode.cc deleted file mode 100644 index 679825cd94f..00000000000 --- a/source/blender/compositor/nodes/COM_FilterNode.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_FilterNode.h" -#include "BKE_node.hh" -#include "COM_ConvolutionEdgeFilterOperation.h" - -namespace blender::compositor { - -FilterNode::FilterNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void FilterNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_image_socket = this->get_input_socket(1); - NodeOutput *output_socket = this->get_output_socket(0); - ConvolutionFilterOperation *operation = nullptr; - - switch (this->get_bnode()->custom1) { - case CMP_NODE_FILTER_SOFT: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(1 / 16.0f, - 2 / 16.0f, - 1 / 16.0f, - 2 / 16.0f, - 4 / 16.0f, - 2 / 16.0f, - 1 / 16.0f, - 2 / 16.0f, - 1 / 16.0f); - break; - case CMP_NODE_FILTER_SHARP_BOX: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(-1, -1, -1, -1, 9, -1, -1, -1, -1); - break; - case CMP_NODE_FILTER_LAPLACE: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(-1 / 8.0f, - -1 / 8.0f, - -1 / 8.0f, - -1 / 8.0f, - 1.0f, - -1 / 8.0f, - -1 / 8.0f, - -1 / 8.0f, - -1 / 8.0f); - break; - case CMP_NODE_FILTER_SOBEL: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(1, 2, 1, 0, 0, 0, -1, -2, -1); - break; - case CMP_NODE_FILTER_PREWITT: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(1, 1, 1, 0, 0, 0, -1, -1, -1); - break; - case CMP_NODE_FILTER_KIRSCH: - operation = new ConvolutionEdgeFilterOperation(); - operation->set3x3Filter(5, 5, 5, -3, -3, -3, -2, -2, -2); - break; - case CMP_NODE_FILTER_SHADOW: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(1, 2, 1, 0, 1, 0, -1, -2, -1); - break; - case CMP_NODE_FILTER_SHARP_DIAMOND: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(0, -1, 0, -1, 5, -1, 0, -1, 0); - break; - default: - operation = new ConvolutionFilterOperation(); - operation->set3x3Filter(0, 0, 0, 0, 1, 0, 0, 0, 0); - break; - } - converter.add_operation(operation); - - converter.map_input_socket(input_image_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_socket, operation->get_input_socket(1)); - converter.map_output_socket(output_socket, operation->get_output_socket()); - - converter.add_preview(operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h deleted file mode 100644 index 3164927672d..00000000000 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief FilterNode - * \ingroup Node - */ -class FilterNode : public Node { - public: - FilterNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FlipNode.cc b/source/blender/compositor/nodes/COM_FlipNode.cc deleted file mode 100644 index f2491554ee1..00000000000 --- a/source/blender/compositor/nodes/COM_FlipNode.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_FlipNode.h" - -#include "COM_FlipOperation.h" - -namespace blender::compositor { - -FlipNode::FlipNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void FlipNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - FlipOperation *operation = new FlipOperation(); - switch (this->get_bnode()->custom1) { - case 0: /* TODO: I didn't find any constants in the old implementation, - * should I introduce them. */ - operation->setFlipX(true); - operation->setFlipY(false); - break; - case 1: - operation->setFlipX(false); - operation->setFlipY(true); - break; - case 2: - operation->setFlipX(true); - operation->setFlipY(true); - break; - } - - converter.add_operation(operation); - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h deleted file mode 100644 index 82fa81fe833..00000000000 --- a/source/blender/compositor/nodes/COM_FlipNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief FlipNode - * \ingroup Node - */ -class FlipNode : public Node { - public: - FlipNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_GammaNode.cc b/source/blender/compositor/nodes/COM_GammaNode.cc deleted file mode 100644 index 4d508e96a93..00000000000 --- a/source/blender/compositor/nodes/COM_GammaNode.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GammaNode.h" -#include "COM_GammaOperation.h" - -namespace blender::compositor { - -GammaNode::GammaNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void GammaNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - GammaOperation *operation = new GammaOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h deleted file mode 100644 index f58c4de2f81..00000000000 --- a/source/blender/compositor/nodes/COM_GammaNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief GammaNode - * \ingroup Node - */ -class GammaNode : public Node { - public: - GammaNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_GlareNode.cc b/source/blender/compositor/nodes/COM_GlareNode.cc deleted file mode 100644 index 380d4b122f6..00000000000 --- a/source/blender/compositor/nodes/COM_GlareNode.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GlareNode.h" -#include "COM_GlareBloomOperation.h" -#include "COM_GlareFogGlowOperation.h" -#include "COM_GlareGhostOperation.h" -#include "COM_GlareSimpleStarOperation.h" -#include "COM_GlareStreaksOperation.h" -#include "COM_GlareThresholdOperation.h" -#include "COM_MixOperation.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -GlareNode::GlareNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void GlareNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - const NodeGlare *glare = (const NodeGlare *)node->storage; - - GlareBaseOperation *glareoperation = nullptr; - switch (glare->type) { - default: - case CMP_NODE_GLARE_GHOST: - glareoperation = new GlareGhostOperation(); - break; - case CMP_NODE_GLARE_STREAKS: - glareoperation = new GlareStreaksOperation(); - break; - case CMP_NODE_GLARE_FOG_GLOW: - glareoperation = new GlareFogGlowOperation(); - break; - case CMP_NODE_GLARE_SIMPLE_STAR: - glareoperation = new GlareSimpleStarOperation(); - break; - case CMP_NODE_GLARE_BLOOM: - glareoperation = new GlareBloomOperation(); - break; - } - BLI_assert(glareoperation); - glareoperation->set_glare_settings(glare); - - GlareThresholdOperation *threshold_operation = new GlareThresholdOperation(); - threshold_operation->set_glare_settings(glare); - - SetValueOperation *mixvalueoperation = new SetValueOperation(); - mixvalueoperation->set_value(glare->mix); - - MixGlareOperation *mixoperation = new MixGlareOperation(); - mixoperation->set_canvas_input_index(1); - mixoperation->get_input_socket(2)->set_resize_mode(ResizeMode::FitAny); - - converter.add_operation(glareoperation); - converter.add_operation(threshold_operation); - converter.add_operation(mixvalueoperation); - converter.add_operation(mixoperation); - - converter.map_input_socket(get_input_socket(0), threshold_operation->get_input_socket(0)); - converter.add_link(threshold_operation->get_output_socket(), - glareoperation->get_input_socket(0)); - - converter.add_link(mixvalueoperation->get_output_socket(), mixoperation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(0), mixoperation->get_input_socket(1)); - converter.add_link(glareoperation->get_output_socket(), mixoperation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(), mixoperation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h deleted file mode 100644 index a8ecf0949cb..00000000000 --- a/source/blender/compositor/nodes/COM_GlareNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief GlareNode - * \ingroup Node - */ -class GlareNode : public Node { - public: - GlareNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cc b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cc deleted file mode 100644 index da00c6a3dc0..00000000000 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_HueSaturationValueCorrectNode.h" - -#include "COM_ConvertOperation.h" -#include "COM_HueSaturationValueCorrectOperation.h" -#include "COM_MixOperation.h" - -namespace blender::compositor { - -HueSaturationValueCorrectNode::HueSaturationValueCorrectNode(bNode *editor_node) - : Node(editor_node) -{ - /* pass */ -} - -void HueSaturationValueCorrectNode::convert_to_operations( - NodeConverter &converter, const CompositorContext & /*context*/) const -{ - NodeInput *value_socket = this->get_input_socket(0); - NodeInput *color_socket = this->get_input_socket(1); - NodeOutput *output_socket = this->get_output_socket(0); - const bNode *editorsnode = get_bnode(); - CurveMapping *storage = (CurveMapping *)editorsnode->storage; - - ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation(); - converter.add_operation(rgbToHSV); - - ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation(); - converter.add_operation(hsvToRGB); - - HueSaturationValueCorrectOperation *changeHSV = new HueSaturationValueCorrectOperation(); - changeHSV->set_curve_mapping(storage); - converter.add_operation(changeHSV); - - MixBlendOperation *blend = new MixBlendOperation(); - blend->set_canvas_input_index(1); - converter.add_operation(blend); - - converter.map_input_socket(color_socket, rgbToHSV->get_input_socket(0)); - converter.add_link(rgbToHSV->get_output_socket(), changeHSV->get_input_socket(0)); - converter.add_link(changeHSV->get_output_socket(), hsvToRGB->get_input_socket(0)); - converter.add_link(hsvToRGB->get_output_socket(), blend->get_input_socket(2)); - converter.map_input_socket(color_socket, blend->get_input_socket(1)); - converter.map_input_socket(value_socket, blend->get_input_socket(0)); - converter.map_output_socket(output_socket, blend->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h deleted file mode 100644 index 3c87299cae2..00000000000 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief HueSaturationValueCorrectNode - * \ingroup Node - */ -class HueSaturationValueCorrectNode : public Node { - public: - HueSaturationValueCorrectNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cc b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cc deleted file mode 100644 index 00619b36f4a..00000000000 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_HueSaturationValueNode.h" - -#include "COM_ChangeHSVOperation.h" -#include "COM_ConvertOperation.h" -#include "COM_MixOperation.h" - -namespace blender::compositor { - -HueSaturationValueNode::HueSaturationValueNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void HueSaturationValueNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *color_socket = this->get_input_socket(0); - NodeInput *hue_socket = this->get_input_socket(1); - NodeInput *saturation_socket = this->get_input_socket(2); - NodeInput *value_socket = this->get_input_socket(3); - NodeInput *fac_socket = this->get_input_socket(4); - NodeOutput *output_socket = this->get_output_socket(0); - - ConvertRGBToHSVOperation *rgbToHSV = new ConvertRGBToHSVOperation(); - converter.add_operation(rgbToHSV); - - ConvertHSVToRGBOperation *hsvToRGB = new ConvertHSVToRGBOperation(); - converter.add_operation(hsvToRGB); - - ChangeHSVOperation *changeHSV = new ChangeHSVOperation(); - converter.map_input_socket(hue_socket, changeHSV->get_input_socket(1)); - converter.map_input_socket(saturation_socket, changeHSV->get_input_socket(2)); - converter.map_input_socket(value_socket, changeHSV->get_input_socket(3)); - converter.add_operation(changeHSV); - - MixBlendOperation *blend = new MixBlendOperation(); - blend->set_canvas_input_index(1); - converter.add_operation(blend); - - converter.map_input_socket(color_socket, rgbToHSV->get_input_socket(0)); - converter.add_link(rgbToHSV->get_output_socket(), changeHSV->get_input_socket(0)); - converter.add_link(changeHSV->get_output_socket(), hsvToRGB->get_input_socket(0)); - converter.add_link(hsvToRGB->get_output_socket(), blend->get_input_socket(2)); - converter.map_input_socket(color_socket, blend->get_input_socket(1)); - converter.map_input_socket(fac_socket, blend->get_input_socket(0)); - converter.map_output_socket(output_socket, blend->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h deleted file mode 100644 index 2789b07dfaa..00000000000 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief HueSaturationValueNode - * \ingroup Node - */ -class HueSaturationValueNode : public Node { - public: - HueSaturationValueNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.cc b/source/blender/compositor/nodes/COM_IDMaskNode.cc deleted file mode 100644 index 98a0dc638e9..00000000000 --- a/source/blender/compositor/nodes/COM_IDMaskNode.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_IDMaskNode.h" -#include "COM_IDMaskOperation.h" -#include "COM_SMAAOperation.h" - -namespace blender::compositor { - -IDMaskNode::IDMaskNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} -void IDMaskNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *bnode = this->get_bnode(); - - IDMaskOperation *operation; - operation = new IDMaskOperation(); - operation->set_object_index(bnode->custom1); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - if (bnode->custom2 == 0) { - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - else { - SMAAOperation *smaa_operation = new SMAAOperation(); - converter.add_operation(smaa_operation); - converter.add_link(operation->get_output_socket(0), smaa_operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), smaa_operation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h deleted file mode 100644 index 03bea5d31b6..00000000000 --- a/source/blender/compositor/nodes/COM_IDMaskNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief IDMaskNode - * \ingroup Node - */ -class IDMaskNode : public Node { - public: - IDMaskNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ImageNode.cc b/source/blender/compositor/nodes/COM_ImageNode.cc deleted file mode 100644 index de1e655b875..00000000000 --- a/source/blender/compositor/nodes/COM_ImageNode.cc +++ /dev/null @@ -1,264 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_assert.h" - -#include "COM_ConvertOperation.h" -#include "COM_ImageNode.h" -#include "COM_MultilayerImageOperation.h" - -#include "COM_SetColorOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" - -namespace blender::compositor { - -ImageNode::ImageNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} -NodeOperation *ImageNode::do_multilayer_check(NodeConverter &converter, - const CompositorContext &context, - const char *layer_name, - const char *pass_name, - Image *image, - ImageUser *user, - int framenumber, - int outputsocket_index, - DataType datatype) const -{ - NodeOutput *output_socket = this->get_output_socket(outputsocket_index); - MultilayerBaseOperation *operation = nullptr; - switch (datatype) { - case DataType::Value: - operation = new MultilayerValueOperation(); - break; - case DataType::Vector: - operation = new MultilayerVectorOperation(); - break; - case DataType::Color: - operation = new MultilayerColorOperation(); - break; - default: - break; - } - operation->set_image(image); - operation->set_image_user(*user); - operation->set_framenumber(framenumber); - operation->set_render_data(context.get_render_data()); - operation->set_view_name(context.get_view_name()); - operation->set_layer_name(layer_name); - operation->set_pass_name(pass_name); - - converter.add_operation(operation); - converter.map_output_socket(output_socket, operation->get_output_socket()); - - return operation; -} - -void ImageNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - /** Image output */ - NodeOutput *output_image = this->get_output_socket(0); - const bNode *editor_node = this->get_bnode(); - Image *image = (Image *)editor_node->id; - ImageUser *imageuser = (ImageUser *)editor_node->storage; - int framenumber = context.get_framenumber(); - bool output_straight_alpha = (editor_node->custom1 & CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT) != 0; - BKE_image_user_frame_calc(image, imageuser, context.get_framenumber()); - /* Force a load, we assume #ImageUser index will be set OK anyway. */ - if (image && image->type == IMA_TYPE_MULTILAYER) { - bool is_multilayer_ok = false; - ImBuf *ibuf = BKE_image_acquire_ibuf(image, imageuser, nullptr); - RenderResult *rr = BKE_image_acquire_renderresult(nullptr, image); - if (rr) { - RenderLayer *rl = (RenderLayer *)BLI_findlink(&rr->layers, imageuser->layer); - if (rl) { - is_multilayer_ok = true; - - for (int64_t index = 0; index < outputs_.size(); index++) { - NodeOutput *socket = outputs_[index]; - NodeOperation *operation = nullptr; - bNodeSocket *bnode_socket = socket->get_bnode_socket(); - NodeImageLayer *storage = (NodeImageLayer *)bnode_socket->storage; - RenderPass *rpass = (RenderPass *)BLI_findstring( - &rl->passes, storage->pass_name, offsetof(RenderPass, name)); - - if (STREQ(storage->pass_name, RE_PASSNAME_COMBINED) && - STREQ(bnode_socket->name, "Alpha")) - { - /* Alpha output is already handled with the associated combined output. */ - continue; - } - - if (rpass) { - switch (rpass->channels) { - case 1: - operation = do_multilayer_check(converter, - context, - rl->name, - rpass->name, - image, - imageuser, - framenumber, - index, - DataType::Value); - break; - /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */ - /* XXX any way to detect actual vector images? */ - case 3: - operation = do_multilayer_check(converter, - context, - rl->name, - rpass->name, - image, - imageuser, - framenumber, - index, - DataType::Vector); - break; - case 4: - operation = do_multilayer_check(converter, - context, - rl->name, - rpass->name, - image, - imageuser, - framenumber, - index, - DataType::Color); - break; - default: - /* dummy operation is added below */ - break; - } - if (operation && index == 0) { - converter.add_preview(operation->get_output_socket()); - } - if (operation && STREQ(rpass->name, RE_PASSNAME_COMBINED) && - !(bnode_socket->flag & SOCK_UNAVAIL)) - { - for (NodeOutput *alpha_socket : get_output_sockets()) { - bNodeSocket *bnode_alpha_socket = alpha_socket->get_bnode_socket(); - if (!STREQ(bnode_alpha_socket->name, "Alpha")) { - continue; - } - NodeImageLayer *alpha_storage = (NodeImageLayer *)bnode_socket->storage; - if (!STREQ(alpha_storage->pass_name, RE_PASSNAME_COMBINED)) { - continue; - } - SeparateChannelOperation *separate_operation; - separate_operation = new SeparateChannelOperation(); - separate_operation->set_channel(3); - converter.add_operation(separate_operation); - converter.add_link(operation->get_output_socket(), - separate_operation->get_input_socket(0)); - converter.map_output_socket(alpha_socket, separate_operation->get_output_socket()); - break; - } - } - } - - /* In case we can't load the layer. */ - if (operation == nullptr) { - converter.set_invalid_output(get_output_socket(index)); - } - } - } - } - BKE_image_release_renderresult(nullptr, image, rr); - BKE_image_release_ibuf(image, ibuf, nullptr); - - /* without this, multilayer that fail to load will crash blender #32490. */ - if (is_multilayer_ok == false) { - for (NodeOutput *output : get_output_sockets()) { - converter.set_invalid_output(output); - } - } - } - else { - const int64_t number_of_outputs = get_output_sockets().size(); - if (number_of_outputs > 0) { - ImageOperation *operation = new ImageOperation(); - operation->set_image(image); - operation->set_image_user(*imageuser); - operation->set_framenumber(framenumber); - operation->set_render_data(context.get_render_data()); - operation->set_view_name(context.get_view_name()); - converter.add_operation(operation); - - if (output_straight_alpha) { - NodeOperation *alpha_convert_operation = new ConvertPremulToStraightOperation(); - - converter.add_operation(alpha_convert_operation); - converter.map_output_socket(output_image, alpha_convert_operation->get_output_socket()); - converter.add_link(operation->get_output_socket(0), - alpha_convert_operation->get_input_socket(0)); - } - else { - converter.map_output_socket(output_image, operation->get_output_socket()); - } - - converter.add_preview(operation->get_output_socket()); - } - - if (number_of_outputs > 1) { - NodeOutput *alpha_image = this->get_output_socket(1); - ImageAlphaOperation *alpha_operation = new ImageAlphaOperation(); - alpha_operation->set_image(image); - alpha_operation->set_image_user(*imageuser); - alpha_operation->set_framenumber(framenumber); - alpha_operation->set_render_data(context.get_render_data()); - alpha_operation->set_view_name(context.get_view_name()); - converter.add_operation(alpha_operation); - - converter.map_output_socket(alpha_image, alpha_operation->get_output_socket()); - } - else { - /* happens when unlinking image datablock from multilayer node */ - for (int i = 2; i < number_of_outputs; i++) { - NodeOutput *output = this->get_output_socket(i); - NodeOperation *operation = nullptr; - switch (output->get_data_type()) { - case DataType::Value: { - SetValueOperation *valueoperation = new SetValueOperation(); - valueoperation->set_value(0.0f); - operation = valueoperation; - break; - } - case DataType::Vector: { - SetVectorOperation *vectoroperation = new SetVectorOperation(); - vectoroperation->setX(0.0f); - vectoroperation->setY(0.0f); - vectoroperation->setW(0.0f); - operation = vectoroperation; - break; - } - case DataType::Color: { - SetColorOperation *coloroperation = new SetColorOperation(); - coloroperation->set_channel1(0.0f); - coloroperation->set_channel2(0.0f); - coloroperation->set_channel3(0.0f); - coloroperation->set_channel4(0.0f); - operation = coloroperation; - break; - } - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } - - if (operation) { - /* not supporting multiview for this generic case */ - converter.add_operation(operation); - converter.map_output_socket(output, operation->get_output_socket()); - } - } - } - } -} // namespace blender::compositor - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ImageNode.h b/source/blender/compositor/nodes/COM_ImageNode.h deleted file mode 100644 index ac802eeffcb..00000000000 --- a/source/blender/compositor/nodes/COM_ImageNode.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "COM_defines.h" -#include "DNA_image_types.h" -#include "DNA_node_types.h" - -#include "RE_engine.h" -#include "RE_pipeline.h" - -namespace blender::compositor { - -/** - * \brief ImageNode - * \ingroup Node - */ -class ImageNode : public Node { - private: - NodeOperation *do_multilayer_check(NodeConverter &converter, - const CompositorContext &context, - const char *layer_name, - const char *pass_name, - Image *image, - ImageUser *user, - int framenumber, - int outputsocket_index, - DataType datatype) const; - - public: - ImageNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_InpaintNode.cc b/source/blender/compositor/nodes/COM_InpaintNode.cc deleted file mode 100644 index e32df8026fa..00000000000 --- a/source/blender/compositor/nodes/COM_InpaintNode.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_InpaintNode.h" -#include "COM_InpaintOperation.h" - -namespace blender::compositor { - -InpaintNode::InpaintNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void InpaintNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - - const bNode *editor_node = this->get_bnode(); - - /* if (editor_node->custom1 == CMP_NODE_INPAINT_SIMPLE) { */ - if (true) { - InpaintSimpleOperation *operation = new InpaintSimpleOperation(); - operation->set_max_distance(editor_node->custom2); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_InpaintNode.h b/source/blender/compositor/nodes/COM_InpaintNode.h deleted file mode 100644 index 682fb6a2bd2..00000000000 --- a/source/blender/compositor/nodes/COM_InpaintNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief InpaintNode - * \ingroup Node - */ -class InpaintNode : public Node { - public: - InpaintNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_InvertNode.cc b/source/blender/compositor/nodes/COM_InvertNode.cc deleted file mode 100644 index bd589959878..00000000000 --- a/source/blender/compositor/nodes/COM_InvertNode.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_InvertNode.h" -#include "BKE_node.hh" -#include "COM_InvertOperation.h" - -namespace blender::compositor { - -InvertNode::InvertNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void InvertNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - InvertOperation *operation = new InvertOperation(); - const bNode *node = this->get_bnode(); - operation->set_color(node->custom1 & CMP_CHAN_RGB); - operation->set_alpha(node->custom1 & CMP_CHAN_A); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h deleted file mode 100644 index c6ed6ed35ad..00000000000 --- a/source/blender/compositor/nodes/COM_InvertNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief InvertNode - * \ingroup Node - */ -class InvertNode : public Node { - public: - InvertNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cc b/source/blender/compositor/nodes/COM_KeyingNode.cc deleted file mode 100644 index eb84439ebb4..00000000000 --- a/source/blender/compositor/nodes/COM_KeyingNode.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingNode.h" - -#include "COM_KeyingBlurOperation.h" -#include "COM_KeyingClipOperation.h" -#include "COM_KeyingDespillOperation.h" -#include "COM_KeyingOperation.h" - -#include "COM_MathBaseOperation.h" - -#include "COM_ConvertOperation.h" -#include "COM_SetValueOperation.h" - -#include "COM_DilateErodeOperation.h" - -#include "COM_SetAlphaMultiplyOperation.h" - -#include "COM_GaussianAlphaBlurBaseOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -KeyingNode::KeyingNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -NodeOperationOutput *KeyingNode::setup_pre_blur(NodeConverter &converter, - NodeInput *input_image, - int size) const -{ - ConvertRGBToYCCOperation *convertRGBToYCCOperation = new ConvertRGBToYCCOperation(); - convertRGBToYCCOperation->set_mode(BLI_YCC_ITU_BT709); - converter.add_operation(convertRGBToYCCOperation); - - converter.map_input_socket(input_image, convertRGBToYCCOperation->get_input_socket(0)); - - CombineChannelsOperation *combine_operation = new CombineChannelsOperation(); - converter.add_operation(combine_operation); - - for (int channel = 0; channel < 4; channel++) { - SeparateChannelOperation *separate_operation = new SeparateChannelOperation(); - separate_operation->set_channel(channel); - converter.add_operation(separate_operation); - - converter.add_link(convertRGBToYCCOperation->get_output_socket(0), - separate_operation->get_input_socket(0)); - - if (ELEM(channel, 0, 3)) { - converter.add_link(separate_operation->get_output_socket(0), - combine_operation->get_input_socket(channel)); - } - else { - KeyingBlurOperation *blur_xoperation = new KeyingBlurOperation(); - blur_xoperation->set_size(size); - blur_xoperation->set_axis(KeyingBlurOperation::BLUR_AXIS_X); - converter.add_operation(blur_xoperation); - - KeyingBlurOperation *blur_yoperation = new KeyingBlurOperation(); - blur_yoperation->set_size(size); - blur_yoperation->set_axis(KeyingBlurOperation::BLUR_AXIS_Y); - converter.add_operation(blur_yoperation); - - converter.add_link(separate_operation->get_output_socket(), - blur_xoperation->get_input_socket(0)); - converter.add_link(blur_xoperation->get_output_socket(), - blur_yoperation->get_input_socket(0)); - converter.add_link(blur_yoperation->get_output_socket(0), - combine_operation->get_input_socket(channel)); - } - } - - ConvertYCCToRGBOperation *convertYCCToRGBOperation = new ConvertYCCToRGBOperation(); - convertYCCToRGBOperation->set_mode(BLI_YCC_ITU_BT709); - converter.add_operation(convertYCCToRGBOperation); - - converter.add_link(combine_operation->get_output_socket(0), - convertYCCToRGBOperation->get_input_socket(0)); - - return convertYCCToRGBOperation->get_output_socket(0); -} - -NodeOperationOutput *KeyingNode::setup_post_blur(NodeConverter &converter, - NodeOperationOutput *post_blur_input, - int size) const -{ - KeyingBlurOperation *blur_xoperation = new KeyingBlurOperation(); - blur_xoperation->set_size(size); - blur_xoperation->set_axis(KeyingBlurOperation::BLUR_AXIS_X); - converter.add_operation(blur_xoperation); - - KeyingBlurOperation *blur_yoperation = new KeyingBlurOperation(); - blur_yoperation->set_size(size); - blur_yoperation->set_axis(KeyingBlurOperation::BLUR_AXIS_Y); - converter.add_operation(blur_yoperation); - - converter.add_link(post_blur_input, blur_xoperation->get_input_socket(0)); - converter.add_link(blur_xoperation->get_output_socket(), blur_yoperation->get_input_socket(0)); - - return blur_yoperation->get_output_socket(); -} - -NodeOperationOutput *KeyingNode::setup_dilate_erode(NodeConverter &converter, - NodeOperationOutput *dilate_erode_input, - int distance) const -{ - DilateDistanceOperation *dilate_erode_operation; - if (distance > 0) { - dilate_erode_operation = new DilateDistanceOperation(); - dilate_erode_operation->set_distance(distance); - } - else { - dilate_erode_operation = new ErodeDistanceOperation(); - dilate_erode_operation->set_distance(-distance); - } - converter.add_operation(dilate_erode_operation); - - converter.add_link(dilate_erode_input, dilate_erode_operation->get_input_socket(0)); - - return dilate_erode_operation->get_output_socket(0); -} - -NodeOperationOutput *KeyingNode::setup_feather(NodeConverter &converter, - const CompositorContext & /*context*/, - NodeOperationOutput *feather_input, - int falloff, - int distance) const -{ - /* initialize node data */ - NodeBlurData data; - memset(&data, 0, sizeof(NodeBlurData)); - data.filtertype = R_FILTER_GAUSS; - if (distance > 0) { - data.sizex = data.sizey = distance; - } - else { - data.sizex = data.sizey = -distance; - } - - GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation(); - operationx->set_data(&data); - operationx->set_size(1.0f); - operationx->set_subtract(distance < 0); - operationx->set_falloff(falloff); - converter.add_operation(operationx); - - GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation(); - operationy->set_data(&data); - operationy->set_size(1.0f); - operationy->set_subtract(distance < 0); - operationy->set_falloff(falloff); - converter.add_operation(operationy); - - converter.add_link(feather_input, operationx->get_input_socket(0)); - converter.add_link(operationx->get_output_socket(), operationy->get_input_socket(0)); - - return operationy->get_output_socket(); -} - -NodeOperationOutput *KeyingNode::setup_despill(NodeConverter &converter, - NodeOperationOutput *despill_input, - NodeInput *input_screen, - float factor, - float color_balance) const -{ - KeyingDespillOperation *despill_operation = new KeyingDespillOperation(); - despill_operation->set_despill_factor(factor); - despill_operation->set_color_balance(color_balance); - converter.add_operation(despill_operation); - - converter.add_link(despill_input, despill_operation->get_input_socket(0)); - converter.map_input_socket(input_screen, despill_operation->get_input_socket(1)); - - return despill_operation->get_output_socket(0); -} - -NodeOperationOutput *KeyingNode::setup_clip(NodeConverter &converter, - NodeOperationOutput *clip_input, - int kernel_radius, - float kernel_tolerance, - float clip_black, - float clip_white, - bool edge_matte) const -{ - KeyingClipOperation *clip_operation = new KeyingClipOperation(); - clip_operation->set_kernel_radius(kernel_radius); - clip_operation->set_kernel_tolerance(kernel_tolerance); - clip_operation->set_clip_black(clip_black); - clip_operation->set_clip_white(clip_white); - clip_operation->set_is_edge_matte(edge_matte); - converter.add_operation(clip_operation); - - converter.add_link(clip_input, clip_operation->get_input_socket(0)); - - return clip_operation->get_output_socket(0); -} - -void KeyingNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - const NodeKeyingData *keying_data = (const NodeKeyingData *)editor_node->storage; - - NodeInput *input_image = this->get_input_socket(0); - NodeInput *input_screen = this->get_input_socket(1); - NodeInput *input_garbage_matte = this->get_input_socket(2); - NodeInput *input_core_matte = this->get_input_socket(3); - NodeOutput *output_image = this->get_output_socket(0); - NodeOutput *output_matte = this->get_output_socket(1); - NodeOutput *output_edges = this->get_output_socket(2); - NodeOperationOutput *postprocessed_matte = nullptr, *postprocessed_image = nullptr, - *edges_matte = nullptr; - - /* keying operation */ - KeyingOperation *keying_operation = new KeyingOperation(); - keying_operation->set_screen_balance(keying_data->screen_balance); - converter.add_operation(keying_operation); - - converter.map_input_socket(input_screen, keying_operation->get_input_socket(1)); - - if (keying_data->blur_pre) { - /* Chroma pre-blur operation for input of keying operation. */ - NodeOperationOutput *pre_blurred_image = setup_pre_blur( - converter, input_image, keying_data->blur_pre); - converter.add_link(pre_blurred_image, keying_operation->get_input_socket(0)); - } - else { - converter.map_input_socket(input_image, keying_operation->get_input_socket(0)); - } - - postprocessed_matte = keying_operation->get_output_socket(); - - /* black / white clipping */ - if (keying_data->clip_black > 0.0f || keying_data->clip_white < 1.0f) { - postprocessed_matte = setup_clip(converter, - postprocessed_matte, - keying_data->edge_kernel_radius, - keying_data->edge_kernel_tolerance, - keying_data->clip_black, - keying_data->clip_white, - false); - } - - /* output edge matte */ - edges_matte = setup_clip(converter, - postprocessed_matte, - keying_data->edge_kernel_radius, - keying_data->edge_kernel_tolerance, - keying_data->clip_black, - keying_data->clip_white, - true); - - /* apply garbage matte */ - if (input_garbage_matte->is_linked()) { - SetValueOperation *value_operation = new SetValueOperation(); - value_operation->set_value(1.0f); - converter.add_operation(value_operation); - - MathSubtractOperation *subtract_operation = new MathSubtractOperation(); - converter.add_operation(subtract_operation); - - MathMinimumOperation *min_operation = new MathMinimumOperation(); - converter.add_operation(min_operation); - - converter.add_link(value_operation->get_output_socket(), - subtract_operation->get_input_socket(0)); - converter.map_input_socket(input_garbage_matte, subtract_operation->get_input_socket(1)); - - converter.add_link(subtract_operation->get_output_socket(), - min_operation->get_input_socket(0)); - converter.add_link(postprocessed_matte, min_operation->get_input_socket(1)); - - postprocessed_matte = min_operation->get_output_socket(); - } - - /* apply core matte */ - if (input_core_matte->is_linked()) { - MathMaximumOperation *max_operation = new MathMaximumOperation(); - converter.add_operation(max_operation); - - converter.map_input_socket(input_core_matte, max_operation->get_input_socket(0)); - converter.add_link(postprocessed_matte, max_operation->get_input_socket(1)); - - postprocessed_matte = max_operation->get_output_socket(); - } - - /* apply blur on matte if needed */ - if (keying_data->blur_post) { - postprocessed_matte = setup_post_blur(converter, postprocessed_matte, keying_data->blur_post); - } - - /* matte dilate/erode */ - if (keying_data->dilate_distance != 0) { - postprocessed_matte = setup_dilate_erode( - converter, postprocessed_matte, keying_data->dilate_distance); - } - - /* matte feather */ - if (keying_data->feather_distance != 0) { - postprocessed_matte = setup_feather(converter, - context, - postprocessed_matte, - keying_data->feather_falloff, - keying_data->feather_distance); - } - - /* set alpha channel to output image */ - SetAlphaMultiplyOperation *alpha_operation = new SetAlphaMultiplyOperation(); - converter.add_operation(alpha_operation); - - converter.map_input_socket(input_image, alpha_operation->get_input_socket(0)); - converter.add_link(postprocessed_matte, alpha_operation->get_input_socket(1)); - - postprocessed_image = alpha_operation->get_output_socket(); - - /* despill output image */ - if (keying_data->despill_factor > 0.0f) { - postprocessed_image = setup_despill(converter, - postprocessed_image, - input_screen, - keying_data->despill_factor, - keying_data->despill_balance); - } - - /* connect result to output sockets */ - converter.map_output_socket(output_image, postprocessed_image); - converter.map_output_socket(output_matte, postprocessed_matte); - - if (edges_matte) { - converter.map_output_socket(output_edges, edges_matte); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h deleted file mode 100644 index 7f707b645a8..00000000000 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief KeyingNode - * \ingroup Node - */ -class KeyingNode : public Node { - protected: - NodeOperationOutput *setup_pre_blur(NodeConverter &converter, - NodeInput *input_image, - int size) const; - NodeOperationOutput *setup_post_blur(NodeConverter &converter, - NodeOperationOutput *post_blur_input, - int size) const; - NodeOperationOutput *setup_dilate_erode(NodeConverter &converter, - NodeOperationOutput *dilate_erode_input, - int distance) const; - NodeOperationOutput *setup_feather(NodeConverter &converter, - const CompositorContext &context, - NodeOperationOutput *feather_input, - int falloff, - int distance) const; - NodeOperationOutput *setup_despill(NodeConverter &converter, - NodeOperationOutput *despill_input, - NodeInput *input_screen, - float factor, - float color_balance) const; - NodeOperationOutput *setup_clip(NodeConverter &converter, - NodeOperationOutput *clip_input, - int kernel_radius, - float kernel_tolerance, - float clip_black, - float clip_white, - bool edge_matte) const; - - public: - KeyingNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cc b/source/blender/compositor/nodes/COM_KeyingScreenNode.cc deleted file mode 100644 index a966c3181e0..00000000000 --- a/source/blender/compositor/nodes/COM_KeyingScreenNode.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingScreenNode.h" -#include "COM_KeyingScreenOperation.h" - -namespace blender::compositor { - -KeyingScreenNode::KeyingScreenNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void KeyingScreenNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - MovieClip *clip = (MovieClip *)editor_node->id; - NodeKeyingScreenData *keyingscreen_data = (NodeKeyingScreenData *)editor_node->storage; - - NodeOutput *output_screen = this->get_output_socket(0); - - /* Always connect the output image. */ - KeyingScreenOperation *operation = new KeyingScreenOperation(); - operation->set_movie_clip(clip); - operation->set_tracking_object(keyingscreen_data->tracking_object); - operation->set_smoothness(keyingscreen_data->smoothness); - operation->set_framenumber(context.get_framenumber()); - converter.add_operation(operation); - - converter.map_output_socket(output_screen, operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.h b/source/blender/compositor/nodes/COM_KeyingScreenNode.h deleted file mode 100644 index 283109712b8..00000000000 --- a/source/blender/compositor/nodes/COM_KeyingScreenNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief KeyingScreenNode - * \ingroup Node - */ -class KeyingScreenNode : public Node { - public: - KeyingScreenNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KuwaharaNode.cc b/source/blender/compositor/nodes/COM_KuwaharaNode.cc deleted file mode 100644 index 8219fa3b4fd..00000000000 --- a/source/blender/compositor/nodes/COM_KuwaharaNode.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "DNA_node_types.h" -#include "DNA_scene_types.h" - -#include "COM_KuwaharaNode.h" - -#include "COM_GaussianBlurBaseOperation.h" -#include "COM_KuwaharaAnisotropicOperation.h" -#include "COM_KuwaharaAnisotropicStructureTensorOperation.h" -#include "COM_KuwaharaClassicOperation.h" -#include "COM_SummedAreaTableOperation.h" - -namespace blender::compositor { - -void KuwaharaNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - const NodeKuwaharaData *data = (const NodeKuwaharaData *)node->storage; - - switch (data->variation) { - case CMP_NODE_KUWAHARA_CLASSIC: { - KuwaharaClassicOperation *kuwahara_classic = new KuwaharaClassicOperation(); - kuwahara_classic->set_high_precision(data->high_precision); - converter.add_operation(kuwahara_classic); - converter.map_input_socket(get_input_socket(0), kuwahara_classic->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), kuwahara_classic->get_input_socket(1)); - - SummedAreaTableOperation *sat = new SummedAreaTableOperation(); - sat->set_mode(SummedAreaTableOperation::eMode::Identity); - converter.add_operation(sat); - converter.map_input_socket(get_input_socket(0), sat->get_input_socket(0)); - converter.add_link(sat->get_output_socket(0), kuwahara_classic->get_input_socket(2)); - - SummedAreaTableOperation *sat_squared = new SummedAreaTableOperation(); - sat_squared->set_mode(SummedAreaTableOperation::eMode::Squared); - converter.add_operation(sat_squared); - converter.map_input_socket(get_input_socket(0), sat_squared->get_input_socket(0)); - converter.add_link(sat_squared->get_output_socket(0), kuwahara_classic->get_input_socket(3)); - - converter.map_output_socket(get_output_socket(0), kuwahara_classic->get_output_socket(0)); - break; - } - - case CMP_NODE_KUWAHARA_ANISOTROPIC: { - KuwaharaAnisotropicStructureTensorOperation *structure_tensor_operation = - new KuwaharaAnisotropicStructureTensorOperation(); - converter.add_operation(structure_tensor_operation); - converter.map_input_socket(get_input_socket(0), - structure_tensor_operation->get_input_socket(0)); - - NodeBlurData blur_data; - blur_data.sizex = data->uniformity; - blur_data.sizey = data->uniformity; - blur_data.relative = false; - blur_data.filtertype = R_FILTER_GAUSS; - - GaussianXBlurOperation *blur_x_operation = new GaussianXBlurOperation(); - blur_x_operation->set_data(&blur_data); - blur_x_operation->set_size(1.0f); - - converter.add_operation(blur_x_operation); - converter.add_link(structure_tensor_operation->get_output_socket(0), - blur_x_operation->get_input_socket(0)); - - GaussianYBlurOperation *blur_y_operation = new GaussianYBlurOperation(); - blur_y_operation->set_data(&blur_data); - blur_y_operation->set_size(1.0f); - - converter.add_operation(blur_y_operation); - converter.add_link(blur_x_operation->get_output_socket(0), - blur_y_operation->get_input_socket(0)); - - KuwaharaAnisotropicOperation *kuwahara_anisotropic_operation = - new KuwaharaAnisotropicOperation(); - kuwahara_anisotropic_operation->set_sharpness(data->sharpness); - kuwahara_anisotropic_operation->set_eccentricity(data->eccentricity); - - converter.add_operation(kuwahara_anisotropic_operation); - converter.map_input_socket(get_input_socket(0), - kuwahara_anisotropic_operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), - kuwahara_anisotropic_operation->get_input_socket(1)); - converter.add_link(blur_y_operation->get_output_socket(0), - kuwahara_anisotropic_operation->get_input_socket(2)); - - converter.map_output_socket(get_output_socket(0), - kuwahara_anisotropic_operation->get_output_socket(0)); - - break; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_KuwaharaNode.h b/source/blender/compositor/nodes/COM_KuwaharaNode.h deleted file mode 100644 index 27c27a565ce..00000000000 --- a/source/blender/compositor/nodes/COM_KuwaharaNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief KuwaharaNode - * \ingroup Node - */ -class KuwaharaNode : public Node { - public: - KuwaharaNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cc b/source/blender/compositor/nodes/COM_LensDistortionNode.cc deleted file mode 100644 index 72d966d7b25..00000000000 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_LensDistortionNode.h" -#include "COM_ProjectorLensDistortionOperation.h" -#include "COM_ScreenLensDistortionOperation.h" - -namespace blender::compositor { - -LensDistortionNode::LensDistortionNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void LensDistortionNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - NodeLensDist *data = (NodeLensDist *)editor_node->storage; - if (data->proj) { - ProjectorLensDistortionOperation *operation = new ProjectorLensDistortionOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } - else { - ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation(); - operation->set_fit(data->fit); - operation->set_jitter(data->jit); - - if (!get_input_socket(1)->is_linked()) { - operation->set_distortion(get_input_socket(1)->get_editor_value_float()); - } - if (!get_input_socket(2)->is_linked()) { - operation->set_dispersion(get_input_socket(2)->get_editor_value_float()); - } - - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h deleted file mode 100644 index ef4d1e0f4aa..00000000000 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief LensDistortionNode - * \ingroup Node - */ -class LensDistortionNode : public Node { - public: - LensDistortionNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cc b/source/blender/compositor/nodes/COM_LuminanceMatteNode.cc deleted file mode 100644 index 49fee092a48..00000000000 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_LuminanceMatteNode.h" -#include "COM_LuminanceMatteOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -LuminanceMatteNode::LuminanceMatteNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void LuminanceMatteNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editorsnode = get_bnode(); - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket_image = this->get_output_socket(0); - NodeOutput *output_socket_matte = this->get_output_socket(1); - - LuminanceMatteOperation *operation_set = new LuminanceMatteOperation(); - operation_set->set_settings((NodeChroma *)editorsnode->storage); - converter.add_operation(operation_set); - - converter.map_input_socket(input_socket, operation_set->get_input_socket(0)); - converter.map_output_socket(output_socket_matte, operation_set->get_output_socket(0)); - - SetAlphaMultiplyOperation *operation = new SetAlphaMultiplyOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.add_link(operation_set->get_output_socket(), operation->get_input_socket(1)); - converter.map_output_socket(output_socket_image, operation->get_output_socket()); - - converter.add_preview(operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h deleted file mode 100644 index 7ac2c4ee1bb..00000000000 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief LuminanceMatteNode - * \ingroup Node - */ -class LuminanceMatteNode : public Node { - public: - LuminanceMatteNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.cc b/source/blender/compositor/nodes/COM_MapRangeNode.cc deleted file mode 100644 index 2ffe5bd44b0..00000000000 --- a/source/blender/compositor/nodes/COM_MapRangeNode.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapRangeNode.h" - -#include "COM_MapRangeOperation.h" - -namespace blender::compositor { - -MapRangeNode::MapRangeNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MapRangeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *value_socket = this->get_input_socket(0); - NodeInput *source_min_socket = this->get_input_socket(1); - NodeInput *source_max_socket = this->get_input_socket(2); - NodeInput *dest_min_socket = this->get_input_socket(3); - NodeInput *dest_max_socket = this->get_input_socket(4); - NodeOutput *output_socket = this->get_output_socket(0); - - MapRangeOperation *operation = new MapRangeOperation(); - operation->set_use_clamp(this->get_bnode()->custom1); - converter.add_operation(operation); - - converter.map_input_socket(value_socket, operation->get_input_socket(0)); - converter.map_input_socket(source_min_socket, operation->get_input_socket(1)); - converter.map_input_socket(source_max_socket, operation->get_input_socket(2)); - converter.map_input_socket(dest_min_socket, operation->get_input_socket(3)); - converter.map_input_socket(dest_max_socket, operation->get_input_socket(4)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapRangeNode.h b/source/blender/compositor/nodes/COM_MapRangeNode.h deleted file mode 100644 index 30dffe566e4..00000000000 --- a/source/blender/compositor/nodes/COM_MapRangeNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief MapRangeNode - * \ingroup Node - */ -class MapRangeNode : public Node { - public: - MapRangeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cc b/source/blender/compositor/nodes/COM_MapUVNode.cc deleted file mode 100644 index 21740bf6948..00000000000 --- a/source/blender/compositor/nodes/COM_MapUVNode.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapUVNode.h" -#include "COM_MapUVOperation.h" - -namespace blender::compositor { - -MapUVNode::MapUVNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MapUVNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - - MapUVOperation *operation = new MapUVOperation(); - operation->set_alpha(float(node->custom1)); - operation->set_nearest_neighbour(static_cast(node->custom2) == - CMP_NODE_MAP_UV_FILTERING_NEAREST); - operation->set_canvas_input_index(1); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h deleted file mode 100644 index 90a2e90962c..00000000000 --- a/source/blender/compositor/nodes/COM_MapUVNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief MapUVNode - * \ingroup Node - */ -class MapUVNode : public Node { - public: - MapUVNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapValueNode.cc b/source/blender/compositor/nodes/COM_MapValueNode.cc deleted file mode 100644 index 65a155943eb..00000000000 --- a/source/blender/compositor/nodes/COM_MapValueNode.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapValueNode.h" - -#include "COM_MapValueOperation.h" - -namespace blender::compositor { - -MapValueNode::MapValueNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MapValueNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const TexMapping *storage = (const TexMapping *)this->get_bnode()->storage; - - NodeInput *color_socket = this->get_input_socket(0); - NodeOutput *value_socket = this->get_output_socket(0); - - MapValueOperation *convert_prog = new MapValueOperation(); - convert_prog->set_settings(storage); - converter.add_operation(convert_prog); - - converter.map_input_socket(color_socket, convert_prog->get_input_socket(0)); - converter.map_output_socket(value_socket, convert_prog->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h deleted file mode 100644 index 77d2593eb33..00000000000 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief MapValueNode - * \ingroup Node - */ -class MapValueNode : public Node { - public: - MapValueNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MaskNode.cc b/source/blender/compositor/nodes/COM_MaskNode.cc deleted file mode 100644 index 88cf85199dc..00000000000 --- a/source/blender/compositor/nodes/COM_MaskNode.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MaskNode.h" -#include "COM_MaskOperation.h" -#include "COM_ScaleOperation.h" - -namespace blender::compositor { - -MaskNode::MaskNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MaskNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const RenderData *rd = context.get_render_data(); - const float render_size_factor = context.get_render_percentage_as_factor(); - - NodeOutput *output_mask = this->get_output_socket(0); - - const bNode *editor_node = this->get_bnode(); - const NodeMask *data = (const NodeMask *)editor_node->storage; - Mask *mask = (Mask *)editor_node->id; - - /* Always connect the output image. */ - MaskOperation *operation = new MaskOperation(); - - if (editor_node->custom1 & CMP_NODE_MASK_FLAG_SIZE_FIXED) { - operation->set_mask_width(data->size_x); - operation->set_mask_height(data->size_y); - } - else if (editor_node->custom1 & CMP_NODE_MASK_FLAG_SIZE_FIXED_SCENE) { - operation->set_mask_width(data->size_x * render_size_factor); - operation->set_mask_height(data->size_y * render_size_factor); - } - else { - operation->set_mask_width(rd->xsch * render_size_factor); - operation->set_mask_height(rd->ysch * render_size_factor); - } - - operation->set_mask(mask); - operation->set_framenumber(context.get_framenumber()); - operation->set_feather(bool(editor_node->custom1 & CMP_NODE_MASK_FLAG_NO_FEATHER) == 0); - - if ((editor_node->custom1 & CMP_NODE_MASK_FLAG_MOTION_BLUR) && (editor_node->custom2 > 1) && - (editor_node->custom3 > FLT_EPSILON)) - { - operation->set_motion_blur_samples(editor_node->custom2); - operation->set_motion_blur_shutter(editor_node->custom3); - } - - converter.add_operation(operation); - - ScaleFixedSizeOperation *scale_operation = new ScaleFixedSizeOperation(); - scale_operation->set_variable_size(true); - /* Consider aspect ratio from scene. */ - const int new_height = rd->xasp / rd->yasp * operation->get_mask_height(); - scale_operation->set_new_height(new_height); - scale_operation->set_new_width(operation->get_mask_width()); - scale_operation->set_is_aspect(false); - scale_operation->set_is_crop(false); - scale_operation->set_offset(0.0f, 0.0f); - - converter.add_operation(scale_operation); - converter.add_link(operation->get_output_socket(0), scale_operation->get_input_socket(0)); - - converter.map_output_socket(output_mask, scale_operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h deleted file mode 100644 index aab8ddaf45d..00000000000 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief MaskNode - * \ingroup Node - */ -class MaskNode : public Node { - public: - MaskNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MathNode.cc b/source/blender/compositor/nodes/COM_MathNode.cc deleted file mode 100644 index 4cde5ed9ecf..00000000000 --- a/source/blender/compositor/nodes/COM_MathNode.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MathNode.h" -#include "COM_MathBaseOperation.h" - -namespace blender::compositor { - -void MathNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - MathBaseOperation *operation = nullptr; - - switch (this->get_bnode()->custom1) { - case NODE_MATH_ADD: - operation = new MathAddOperation(); - break; - case NODE_MATH_SUBTRACT: - operation = new MathSubtractOperation(); - break; - case NODE_MATH_MULTIPLY: - operation = new MathMultiplyOperation(); - break; - case NODE_MATH_DIVIDE: - operation = new MathDivideOperation(); - break; - case NODE_MATH_SINE: - operation = new MathSineOperation(); - break; - case NODE_MATH_COSINE: - operation = new MathCosineOperation(); - break; - case NODE_MATH_TANGENT: - operation = new MathTangentOperation(); - break; - case NODE_MATH_ARCSINE: - operation = new MathArcSineOperation(); - break; - case NODE_MATH_ARCCOSINE: - operation = new MathArcCosineOperation(); - break; - case NODE_MATH_ARCTANGENT: - operation = new MathArcTangentOperation(); - break; - case NODE_MATH_SINH: - operation = new MathHyperbolicSineOperation(); - break; - case NODE_MATH_COSH: - operation = new MathHyperbolicCosineOperation(); - break; - case NODE_MATH_TANH: - operation = new MathHyperbolicTangentOperation(); - break; - case NODE_MATH_POWER: - operation = new MathPowerOperation(); - break; - case NODE_MATH_LOGARITHM: - operation = new MathLogarithmOperation(); - break; - case NODE_MATH_MINIMUM: - operation = new MathMinimumOperation(); - break; - case NODE_MATH_MAXIMUM: - operation = new MathMaximumOperation(); - break; - case NODE_MATH_ROUND: - operation = new MathRoundOperation(); - break; - case NODE_MATH_LESS_THAN: - operation = new MathLessThanOperation(); - break; - case NODE_MATH_GREATER_THAN: - operation = new MathGreaterThanOperation(); - break; - case NODE_MATH_MODULO: - operation = new MathModuloOperation(); - break; - case NODE_MATH_FLOORED_MODULO: - operation = new MathFlooredModuloOperation(); - break; - case NODE_MATH_ABSOLUTE: - operation = new MathAbsoluteOperation(); - break; - case NODE_MATH_RADIANS: - operation = new MathRadiansOperation(); - break; - case NODE_MATH_DEGREES: - operation = new MathDegreesOperation(); - break; - case NODE_MATH_ARCTAN2: - operation = new MathArcTan2Operation(); - break; - case NODE_MATH_FLOOR: - operation = new MathFloorOperation(); - break; - case NODE_MATH_CEIL: - operation = new MathCeilOperation(); - break; - case NODE_MATH_FRACTION: - operation = new MathFractOperation(); - break; - case NODE_MATH_SQRT: - operation = new MathSqrtOperation(); - break; - case NODE_MATH_INV_SQRT: - operation = new MathInverseSqrtOperation(); - break; - case NODE_MATH_SIGN: - operation = new MathSignOperation(); - break; - case NODE_MATH_EXPONENT: - operation = new MathExponentOperation(); - break; - case NODE_MATH_TRUNC: - operation = new MathTruncOperation(); - break; - case NODE_MATH_SNAP: - operation = new MathSnapOperation(); - break; - case NODE_MATH_WRAP: - operation = new MathWrapOperation(); - break; - case NODE_MATH_PINGPONG: - operation = new MathPingpongOperation(); - break; - case NODE_MATH_COMPARE: - operation = new MathCompareOperation(); - break; - case NODE_MATH_MULTIPLY_ADD: - operation = new MathMultiplyAddOperation(); - break; - case NODE_MATH_SMOOTH_MIN: - operation = new MathSmoothMinOperation(); - break; - case NODE_MATH_SMOOTH_MAX: - operation = new MathSmoothMaxOperation(); - break; - } - - if (operation) { - bool use_clamp = get_bnode()->custom2; - operation->set_use_clamp(use_clamp); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h deleted file mode 100644 index e7865898267..00000000000 --- a/source/blender/compositor/nodes/COM_MathNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief MathNode - * \ingroup Node - */ -class MathNode : public Node { - public: - MathNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MixNode.cc b/source/blender/compositor/nodes/COM_MixNode.cc deleted file mode 100644 index 58dad960181..00000000000 --- a/source/blender/compositor/nodes/COM_MixNode.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MixNode.h" - -#include "COM_MixOperation.h" - -#include "DNA_material_types.h" /* the ramp types */ - -namespace blender::compositor { - -MixNode::MixNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MixNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *value_socket = this->get_input_socket(0); - NodeInput *color1Socket = this->get_input_socket(1); - NodeInput *color2Socket = this->get_input_socket(2); - NodeOutput *output_socket = this->get_output_socket(0); - const bNode *editor_node = this->get_bnode(); - bool use_alpha_premultiply = (this->get_bnode()->custom2 & 1) != 0; - bool use_clamp = (this->get_bnode()->custom2 & 2) != 0; - - MixBaseOperation *convert_prog; - switch (editor_node->custom1) { - case MA_RAMP_ADD: - convert_prog = new MixAddOperation(); - break; - case MA_RAMP_MULT: - convert_prog = new MixMultiplyOperation(); - break; - case MA_RAMP_LIGHT: - convert_prog = new MixLightenOperation(); - break; - case MA_RAMP_BURN: - convert_prog = new MixColorBurnOperation(); - break; - case MA_RAMP_HUE: - convert_prog = new MixHueOperation(); - break; - case MA_RAMP_COLOR: - convert_prog = new MixColorOperation(); - break; - case MA_RAMP_SOFT: - convert_prog = new MixSoftLightOperation(); - break; - case MA_RAMP_SCREEN: - convert_prog = new MixScreenOperation(); - break; - case MA_RAMP_LINEAR: - convert_prog = new MixLinearLightOperation(); - break; - case MA_RAMP_DIFF: - convert_prog = new MixDifferenceOperation(); - break; - case MA_RAMP_EXCLUSION: - convert_prog = new MixExclusionOperation(); - break; - case MA_RAMP_SAT: - convert_prog = new MixSaturationOperation(); - break; - case MA_RAMP_DIV: - convert_prog = new MixDivideOperation(); - break; - case MA_RAMP_SUB: - convert_prog = new MixSubtractOperation(); - break; - case MA_RAMP_DARK: - convert_prog = new MixDarkenOperation(); - break; - case MA_RAMP_OVERLAY: - convert_prog = new MixOverlayOperation(); - break; - case MA_RAMP_VAL: - convert_prog = new MixValueOperation(); - break; - case MA_RAMP_DODGE: - convert_prog = new MixDodgeOperation(); - break; - - case MA_RAMP_BLEND: - default: - convert_prog = new MixBlendOperation(); - break; - } - convert_prog->set_use_value_alpha_multiply(use_alpha_premultiply); - convert_prog->set_use_clamp(use_clamp); - converter.add_operation(convert_prog); - - converter.map_input_socket(value_socket, convert_prog->get_input_socket(0)); - converter.map_input_socket(color1Socket, convert_prog->get_input_socket(1)); - converter.map_input_socket(color2Socket, convert_prog->get_input_socket(2)); - converter.map_output_socket(output_socket, convert_prog->get_output_socket(0)); - - converter.add_preview(convert_prog->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h deleted file mode 100644 index 9cec58c581a..00000000000 --- a/source/blender/compositor/nodes/COM_MixNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief MixNode - * \ingroup Node - */ -class MixNode : public Node { - public: - MixNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cc b/source/blender/compositor/nodes/COM_MovieClipNode.cc deleted file mode 100644 index 69716593111..00000000000 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MovieClipNode.h" - -#include "COM_MovieClipOperation.h" - -#include "BKE_movieclip.h" -#include "BKE_tracking.h" - -#include "DNA_movieclip_types.h" - -#include "IMB_imbuf.hh" - -namespace blender::compositor { - -MovieClipNode::MovieClipNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MovieClipNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeOutput *output_movie_clip = this->get_output_socket(0); - NodeOutput *alpha_movie_clip = this->get_output_socket(1); - NodeOutput *offset_xmovie_clip = this->get_output_socket(2); - NodeOutput *offset_ymovie_clip = this->get_output_socket(3); - NodeOutput *scale_movie_clip = this->get_output_socket(4); - NodeOutput *angle_movie_clip = this->get_output_socket(5); - - const bNode *editor_node = this->get_bnode(); - MovieClip *movie_clip = (MovieClip *)editor_node->id; - MovieClipUser *movie_clip_user = (MovieClipUser *)editor_node->storage; - bool cache_frame = !context.is_rendering(); - - ImBuf *ibuf = nullptr; - if (movie_clip) { - if (cache_frame) { - ibuf = BKE_movieclip_get_ibuf(movie_clip, movie_clip_user); - } - else { - ibuf = BKE_movieclip_get_ibuf_flag( - movie_clip, movie_clip_user, movie_clip->flag, MOVIECLIP_CACHE_SKIP); - } - } - - /* Always connect the output image. */ - MovieClipOperation *operation = new MovieClipOperation(); - operation->set_movie_clip(movie_clip); - operation->set_movie_clip_user(movie_clip_user); - operation->set_framenumber(context.get_framenumber()); - operation->set_cache_frame(cache_frame); - - converter.add_operation(operation); - converter.map_output_socket(output_movie_clip, operation->get_output_socket()); - converter.add_preview(operation->get_output_socket()); - - MovieClipAlphaOperation *alpha_operation = new MovieClipAlphaOperation(); - alpha_operation->set_movie_clip(movie_clip); - alpha_operation->set_movie_clip_user(movie_clip_user); - alpha_operation->set_framenumber(context.get_framenumber()); - alpha_operation->set_cache_frame(cache_frame); - - converter.add_operation(alpha_operation); - converter.map_output_socket(alpha_movie_clip, alpha_operation->get_output_socket()); - - MovieTrackingStabilization *stab = &movie_clip->tracking.stabilization; - float loc[2], scale, angle; - loc[0] = 0.0f; - loc[1] = 0.0f; - scale = 1.0f; - angle = 0.0f; - - if (ibuf) { - if (stab->flag & TRACKING_2D_STABILIZATION) { - int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movie_clip, - context.get_framenumber()); - - BKE_tracking_stabilization_data_get( - movie_clip, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle); - } - } - - converter.add_output_value(offset_xmovie_clip, loc[0]); - converter.add_output_value(offset_ymovie_clip, loc[1]); - converter.add_output_value(scale_movie_clip, scale); - converter.add_output_value(angle_movie_clip, angle); - - if (ibuf) { - IMB_freeImBuf(ibuf); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h deleted file mode 100644 index 2165b3a793d..00000000000 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief MovieClipNode - * \ingroup Node - */ -class MovieClipNode : public Node { - public: - MovieClipNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.cc b/source/blender/compositor/nodes/COM_MovieDistortionNode.cc deleted file mode 100644 index d3fe65df0dd..00000000000 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MovieDistortionNode.h" - -#include "COM_MovieDistortionOperation.h" - -namespace blender::compositor { - -MovieDistortionNode::MovieDistortionNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void MovieDistortionNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *bnode = this->get_bnode(); - MovieClip *clip = (MovieClip *)bnode->id; - - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - - MovieDistortionOperation *operation = new MovieDistortionOperation(bnode->custom1 == 1); - operation->set_movie_clip(clip); - operation->set_framenumber(context.get_framenumber()); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h deleted file mode 100644 index 12bc889a922..00000000000 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief MovieDistortionNode - * \ingroup Node - */ -class MovieDistortionNode : public Node { - public: - MovieDistortionNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_NormalNode.cc b/source/blender/compositor/nodes/COM_NormalNode.cc deleted file mode 100644 index 7500c477049..00000000000 --- a/source/blender/compositor/nodes/COM_NormalNode.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_NormalNode.h" -#include "COM_DotproductOperation.h" -#include "COM_SetVectorOperation.h" - -namespace blender::compositor { - -NormalNode::NormalNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void NormalNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - NodeOutput *output_socket_dotproduct = this->get_output_socket(1); - - SetVectorOperation *operation_set = new SetVectorOperation(); - float normal[3]; - output_socket->get_editor_value_vector(normal); - /* animation can break normalization, this restores it */ - normalize_v3(normal); - operation_set->setX(normal[0]); - operation_set->setY(normal[1]); - operation_set->setZ(normal[2]); - operation_set->setW(0.0f); - converter.add_operation(operation_set); - - converter.map_output_socket(output_socket, operation_set->get_output_socket(0)); - - DotproductOperation *operation = new DotproductOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.add_link(operation_set->get_output_socket(0), operation->get_input_socket(1)); - converter.map_output_socket(output_socket_dotproduct, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h deleted file mode 100644 index 204edcaefe9..00000000000 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief NormalNode - * \ingroup Node - */ -class NormalNode : public Node { - public: - NormalNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.cc b/source/blender/compositor/nodes/COM_NormalizeNode.cc deleted file mode 100644 index a00d62c3081..00000000000 --- a/source/blender/compositor/nodes/COM_NormalizeNode.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_NormalizeNode.h" -#include "COM_NormalizeOperation.h" - -namespace blender::compositor { - -NormalizeNode::NormalizeNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void NormalizeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NormalizeOperation *operation = new NormalizeOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h deleted file mode 100644 index 3344a527c5c..00000000000 --- a/source/blender/compositor/nodes/COM_NormalizeNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief NormalizeNode - * \ingroup Node - */ -class NormalizeNode : public Node { - public: - NormalizeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cc b/source/blender/compositor/nodes/COM_PixelateNode.cc deleted file mode 100644 index e966351a846..00000000000 --- a/source/blender/compositor/nodes/COM_PixelateNode.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PixelateNode.h" - -#include "COM_PixelateOperation.h" - -namespace blender::compositor { - -PixelateNode::PixelateNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void PixelateNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - - PixelateOperation *operation = new PixelateOperation(); - converter.add_operation(operation); - - operation->set_pixel_size(editor_node->custom1); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PixelateNode.h b/source/blender/compositor/nodes/COM_PixelateNode.h deleted file mode 100644 index 1b070df4173..00000000000 --- a/source/blender/compositor/nodes/COM_PixelateNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief PixelateNode - * \ingroup Node - */ -class PixelateNode : public Node { - public: - PixelateNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cc b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cc deleted file mode 100644 index 8a02e95a855..00000000000 --- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PlaneTrackDeformNode.h" - -#include "COM_PlaneTrackOperation.h" -#include "COM_SMAAOperation.h" -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -PlaneTrackDeformNode::PlaneTrackDeformNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void PlaneTrackDeformNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - MovieClip *clip = (MovieClip *)editor_node->id; - NodePlaneTrackDeformData *data = (NodePlaneTrackDeformData *)editor_node->storage; - - int frame_number = context.get_framenumber(); - - PlaneTrackMaskOperation *plane_mask_operation = new PlaneTrackMaskOperation(); - plane_mask_operation->set_movie_clip(clip); - plane_mask_operation->set_tracking_object(data->tracking_object); - plane_mask_operation->set_plane_track_name(data->plane_track_name); - plane_mask_operation->set_framenumber(frame_number); - if (data->flag & CMP_NODE_PLANE_TRACK_DEFORM_FLAG_MOTION_BLUR) { - plane_mask_operation->set_motion_blur_samples(data->motion_blur_samples); - plane_mask_operation->set_motion_blur_shutter(data->motion_blur_shutter); - } - converter.add_operation(plane_mask_operation); - - SMAAOperation *smaa_operation = new SMAAOperation(); - converter.add_operation(smaa_operation); - - converter.add_link(plane_mask_operation->get_output_socket(), - smaa_operation->get_input_socket(0)); - - converter.map_output_socket(this->get_output_socket(1), smaa_operation->get_output_socket()); - - PlaneTrackWarpImageOperation *warp_image_operation = new PlaneTrackWarpImageOperation(); - warp_image_operation->set_movie_clip(clip); - warp_image_operation->set_tracking_object(data->tracking_object); - warp_image_operation->set_plane_track_name(data->plane_track_name); - warp_image_operation->set_framenumber(frame_number); - if (data->flag & CMP_NODE_PLANE_TRACK_DEFORM_FLAG_MOTION_BLUR) { - warp_image_operation->set_motion_blur_samples(data->motion_blur_samples); - warp_image_operation->set_motion_blur_shutter(data->motion_blur_shutter); - } - converter.add_operation(warp_image_operation); - - converter.map_input_socket(this->get_input_socket(0), warp_image_operation->get_input_socket(0)); - - SetAlphaMultiplyOperation *set_alpha_operation = new SetAlphaMultiplyOperation(); - converter.add_operation(set_alpha_operation); - converter.add_link(warp_image_operation->get_output_socket(), - set_alpha_operation->get_input_socket(0)); - converter.add_link(smaa_operation->get_output_socket(), - set_alpha_operation->get_input_socket(1)); - converter.map_output_socket(this->get_output_socket(0), - set_alpha_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h deleted file mode 100644 index 46e136b842c..00000000000 --- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -#include "DNA_movieclip_types.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief PlaneTrackDeformNode - * \ingroup Node - */ -class PlaneTrackDeformNode : public Node { - public: - PlaneTrackDeformNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PosterizeNode.cc b/source/blender/compositor/nodes/COM_PosterizeNode.cc deleted file mode 100644 index 34f661fc707..00000000000 --- a/source/blender/compositor/nodes/COM_PosterizeNode.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2020 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PosterizeNode.h" -#include "COM_PosterizeOperation.h" - -namespace blender::compositor { - -PosterizeNode::PosterizeNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void PosterizeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - PosterizeOperation *operation = new PosterizeOperation(); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_PosterizeNode.h b/source/blender/compositor/nodes/COM_PosterizeNode.h deleted file mode 100644 index 5f4c5b9e1e0..00000000000 --- a/source/blender/compositor/nodes/COM_PosterizeNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief PosterizeNode - * \ingroup Node - */ -class PosterizeNode : public Node { - public: - PosterizeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cc b/source/blender/compositor/nodes/COM_RenderLayersNode.cc deleted file mode 100644 index 823a8478d60..00000000000 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_RenderLayersNode.h" -#include "COM_SetColorOperation.h" -#include "COM_SetValueOperation.h" -#include "COM_SetVectorOperation.h" - -namespace blender::compositor { - -RenderLayersNode::RenderLayersNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void RenderLayersNode::test_socket_link(NodeConverter &converter, - const CompositorContext &context, - NodeOutput *output, - RenderLayersProg *operation, - Scene *scene, - int layer_id, - bool is_preview) const -{ - operation->set_scene(scene); - operation->set_layer_id(layer_id); - operation->set_render_data(context.get_render_data()); - operation->set_view_name(context.get_view_name()); - - converter.map_output_socket(output, operation->get_output_socket()); - converter.add_operation(operation); - - if (is_preview) { /* only for image socket */ - converter.add_preview(operation->get_output_socket()); - } -} - -void RenderLayersNode::test_render_link(NodeConverter &converter, - const CompositorContext &context, - Render *re) const -{ - Scene *scene = (Scene *)this->get_bnode()->id; - const short layer_id = this->get_bnode()->custom1; - RenderResult *rr = RE_AcquireResultRead(re); - if (rr == nullptr) { - missing_render_link(converter); - return; - } - ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, layer_id); - if (view_layer == nullptr) { - missing_render_link(converter); - return; - } - RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name); - if (rl == nullptr) { - missing_render_link(converter); - return; - } - - for (NodeOutput *output : get_output_sockets()) { - NodeImageLayer *storage = (NodeImageLayer *)output->get_bnode_socket()->storage; - RenderPass *rpass = (RenderPass *)BLI_findstring( - &rl->passes, storage->pass_name, offsetof(RenderPass, name)); - if (rpass == nullptr) { - missing_socket_link(converter, output); - continue; - } - RenderLayersProg *operation; - bool is_preview; - if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && - STREQ(output->get_bnode_socket()->name, "Alpha")) - { - operation = new RenderLayersAlphaProg(rpass->name, DataType::Value, rpass->channels); - is_preview = false; - } - else if (STREQ(rpass->name, RE_PASSNAME_Z)) { - operation = new RenderLayersDepthProg(rpass->name, DataType::Value, rpass->channels); - is_preview = false; - } - else { - DataType type; - switch (rpass->channels) { - case 4: - type = DataType::Color; - break; - case 3: - type = DataType::Vector; - break; - case 1: - type = DataType::Value; - break; - default: - BLI_assert_msg(0, "Unexpected number of channels for pass"); - type = DataType::Value; - break; - } - operation = new RenderLayersProg(rpass->name, type, rpass->channels); - is_preview = STREQ(output->get_bnode_socket()->name, "Image"); - } - test_socket_link(converter, context, output, operation, scene, layer_id, is_preview); - } -} - -void RenderLayersNode::missing_socket_link(NodeConverter &converter, NodeOutput *output) const -{ - NodeOperation *operation; - switch (output->get_data_type()) { - case DataType::Color: { - const float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - SetColorOperation *color_operation = new SetColorOperation(); - color_operation->set_channels(color); - operation = color_operation; - break; - } - case DataType::Vector: { - const float vector[3] = {0.0f, 0.0f, 0.0f}; - SetVectorOperation *vector_operation = new SetVectorOperation(); - vector_operation->set_vector(vector); - operation = vector_operation; - break; - } - case DataType::Value: { - SetValueOperation *value_operation = new SetValueOperation(); - value_operation->set_value(0.0f); - operation = value_operation; - break; - } - default: { - BLI_assert_msg(0, "Unexpected data type"); - return; - } - } - - converter.map_output_socket(output, operation->get_output_socket()); - converter.add_operation(operation); -} - -void RenderLayersNode::missing_render_link(NodeConverter &converter) const -{ - for (NodeOutput *output : outputs_) { - missing_socket_link(converter, output); - } -} - -void RenderLayersNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - Scene *scene = (Scene *)this->get_bnode()->id; - Render *re = (scene) ? RE_GetSceneRender(scene) : nullptr; - - if (re != nullptr) { - test_render_link(converter, context, re); - RE_ReleaseResult(re); - } - else { - missing_render_link(converter); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h deleted file mode 100644 index c11efba646c..00000000000 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "COM_RenderLayersProg.h" -#include "DNA_node_types.h" - -struct Render; -namespace blender::compositor { - -/** - * \brief RenderLayersNode - * \ingroup Node - */ -class RenderLayersNode : public Node { - public: - RenderLayersNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - private: - void test_socket_link(NodeConverter &converter, - const CompositorContext &context, - NodeOutput *output, - RenderLayersProg *operation, - Scene *scene, - int layer_id, - bool is_preview) const; - void test_render_link(NodeConverter &converter, - const CompositorContext &context, - Render *re) const; - - void missing_socket_link(NodeConverter &converter, NodeOutput *output) const; - void missing_render_link(NodeConverter &converter) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_RotateNode.cc b/source/blender/compositor/nodes/COM_RotateNode.cc deleted file mode 100644 index fe0a0ea40a0..00000000000 --- a/source/blender/compositor/nodes/COM_RotateNode.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_RotateNode.h" - -#include "COM_RotateOperation.h" -#include "COM_SetSamplerOperation.h" - -namespace blender::compositor { - -RotateNode::RotateNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void RotateNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_degree_socket = this->get_input_socket(1); - NodeOutput *output_socket = this->get_output_socket(0); - RotateOperation *operation = new RotateOperation(); - converter.add_operation(operation); - - PixelSampler sampler = (PixelSampler)this->get_bnode()->custom1; - operation->set_sampler(sampler); - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - - converter.map_input_socket(input_degree_socket, operation->get_input_socket(1)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h deleted file mode 100644 index 5c49570a240..00000000000 --- a/source/blender/compositor/nodes/COM_RotateNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief RotateNode - * \ingroup Node - */ -class RotateNode : public Node { - public: - RotateNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cc b/source/blender/compositor/nodes/COM_ScaleNode.cc deleted file mode 100644 index f162e6db896..00000000000 --- a/source/blender/compositor/nodes/COM_ScaleNode.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ScaleNode.h" - -#include "BKE_node.hh" -#include "COM_ScaleOperation.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -ScaleNode::ScaleNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ScaleNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *bnode = this->get_bnode(); - - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_xsocket = this->get_input_socket(1); - NodeInput *input_ysocket = this->get_input_socket(2); - NodeOutput *output_socket = this->get_output_socket(0); - - switch (bnode->custom1) { - case CMP_NODE_SCALE_RELATIVE: { - ScaleRelativeOperation *operation = new ScaleRelativeOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_xsocket, operation->get_input_socket(1)); - converter.map_input_socket(input_ysocket, operation->get_input_socket(2)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - - operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked()); - break; - } - case CMP_NODE_SCALE_RENDER_PERCENT: { - SetValueOperation *scale_factor_operation = new SetValueOperation(); - scale_factor_operation->set_value(context.get_render_percentage_as_factor()); - converter.add_operation(scale_factor_operation); - - ScaleRelativeOperation *operation = new ScaleRelativeOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.add_link(scale_factor_operation->get_output_socket(), - operation->get_input_socket(1)); - converter.add_link(scale_factor_operation->get_output_socket(), - operation->get_input_socket(2)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - - operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked()); - - break; - } - case CMP_NODE_SCALE_RENDER_SIZE: { - const RenderData *rd = context.get_render_data(); - const float render_size_factor = context.get_render_percentage_as_factor(); - ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); - /* framing options */ - operation->set_is_aspect( - ELEM(bnode->custom2, CMP_NODE_SCALE_RENDER_SIZE_FIT, CMP_NODE_SCALE_RENDER_SIZE_CROP)); - operation->set_is_crop(bnode->custom2 == CMP_NODE_SCALE_RENDER_SIZE_CROP); - operation->set_offset(bnode->custom3, bnode->custom4); - operation->set_new_width(int(math::round(rd->xsch * render_size_factor))); - operation->set_new_height(int(math::round(rd->ysch * render_size_factor))); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - - operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked()); - - break; - } - case CMP_NODE_SCALE_ABSOLUTE: { - /* TODO: what is the use of this one.... perhaps some issues when the ui was updated... */ - ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation(); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_input_socket(input_xsocket, operation->get_input_socket(1)); - converter.map_input_socket(input_ysocket, operation->get_input_socket(2)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - - operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked()); - - break; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h deleted file mode 100644 index 04b7aff3118..00000000000 --- a/source/blender/compositor/nodes/COM_ScaleNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ScaleNode - * \ingroup Node - */ -class ScaleNode : public Node { - public: - ScaleNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.cc b/source/blender/compositor/nodes/COM_SceneTimeNode.cc deleted file mode 100644 index c1543874d35..00000000000 --- a/source/blender/compositor/nodes/COM_SceneTimeNode.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-FileCopyrightText: 2022 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SceneTimeNode.h" - -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -SceneTimeNode::SceneTimeNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SceneTimeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - SetValueOperation *SecondOperation = new SetValueOperation(); - SetValueOperation *frameOperation = new SetValueOperation(); - - const int frameNumber = context.get_framenumber(); - const Scene *scene = context.get_scene(); - const double frameRate = double(scene->r.frs_sec) / double(scene->r.frs_sec_base); - - SecondOperation->set_value(float(frameNumber / frameRate)); - converter.add_operation(SecondOperation); - - frameOperation->set_value(frameNumber); - converter.add_operation(frameOperation); - - converter.map_output_socket(get_output_socket(0), SecondOperation->get_output_socket()); - converter.map_output_socket(get_output_socket(1), frameOperation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.h b/source/blender/compositor/nodes/COM_SceneTimeNode.h deleted file mode 100644 index f2e7cf38ab6..00000000000 --- a/source/blender/compositor/nodes/COM_SceneTimeNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2022 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SceneTimeNode - * \ingroup Node - */ -class SceneTimeNode : public Node { - public: - SceneTimeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cc b/source/blender/compositor/nodes/COM_SeparateColorNode.cc deleted file mode 100644 index 738f130c49b..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.cc +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SeparateColorNode.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -SeparateColorNode::SeparateColorNode(bNode *editor_node) : Node(editor_node) {} - -void SeparateColorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *image_socket = this->get_input_socket(0); - NodeOutput *output_rsocket = this->get_output_socket(0); - NodeOutput *output_gsocket = this->get_output_socket(1); - NodeOutput *output_bsocket = this->get_output_socket(2); - NodeOutput *output_asocket = this->get_output_socket(3); - - const bNode *editor_node = this->get_bnode(); - const NodeCMPCombSepColor *storage = (const NodeCMPCombSepColor *)editor_node->storage; - - NodeOperation *color_conv = nullptr; - switch (storage->mode) { - case CMP_NODE_COMBSEP_COLOR_RGB: { - /* Pass */ - break; - } - case CMP_NODE_COMBSEP_COLOR_HSV: { - color_conv = new ConvertRGBToHSVOperation(); - break; - } - case CMP_NODE_COMBSEP_COLOR_HSL: { - color_conv = new ConvertRGBToHSLOperation(); - break; - } - case CMP_NODE_COMBSEP_COLOR_YCC: { - ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation(); - operation->set_mode(storage->ycc_mode); - color_conv = operation; - break; - } - case CMP_NODE_COMBSEP_COLOR_YUV: { - color_conv = new ConvertRGBToYUVOperation(); - break; - } - default: { - BLI_assert_unreachable(); - break; - } - } - - if (color_conv) { - converter.add_operation(color_conv); - - converter.map_input_socket(image_socket, color_conv->get_input_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(0); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_rsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(1); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_gsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(2); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_bsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(3); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_asocket, operation->get_output_socket(0)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.h b/source/blender/compositor/nodes/COM_SeparateColorNode.h deleted file mode 100644 index cc36e004592..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -class SeparateColorNode : public Node { - public: - SeparateColorNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.cc b/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.cc deleted file mode 100644 index d5b8b5efcf6..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SeparateColorNodeLegacy.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -SeparateColorNodeLegacy::SeparateColorNodeLegacy(bNode *editor_node) : Node(editor_node) {} - -void SeparateColorNodeLegacy::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeInput *image_socket = this->get_input_socket(0); - NodeOutput *output_rsocket = this->get_output_socket(0); - NodeOutput *output_gsocket = this->get_output_socket(1); - NodeOutput *output_bsocket = this->get_output_socket(2); - NodeOutput *output_asocket = this->get_output_socket(3); - - NodeOperation *color_conv = get_color_converter(context); - if (color_conv) { - converter.add_operation(color_conv); - - converter.map_input_socket(image_socket, color_conv->get_input_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(0); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_rsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(1); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_gsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(2); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_bsocket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(3); - converter.add_operation(operation); - - if (color_conv) { - converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0)); - } - else { - converter.map_input_socket(image_socket, operation->get_input_socket(0)); - } - converter.map_output_socket(output_asocket, operation->get_output_socket(0)); - } -} - -NodeOperation *SeparateRGBANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return nullptr; /* no conversion needed */ -} - -NodeOperation *SeparateHSVANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return new ConvertRGBToHSVOperation(); -} - -NodeOperation *SeparateYCCANode::get_color_converter(const CompositorContext & /*context*/) const -{ - ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation(); - const bNode *editor_node = this->get_bnode(); - operation->set_mode(editor_node->custom1); - return operation; -} - -NodeOperation *SeparateYUVANode::get_color_converter(const CompositorContext & /*context*/) const -{ - return new ConvertRGBToYUVOperation(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.h b/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.h deleted file mode 100644 index e0c826dc405..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateColorNodeLegacy.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -class SeparateColorNodeLegacy : public Node { - public: - SeparateColorNodeLegacy(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - protected: - virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0; -}; - -class SeparateRGBANode : public SeparateColorNodeLegacy { - public: - SeparateRGBANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class SeparateHSVANode : public SeparateColorNodeLegacy { - public: - SeparateHSVANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class SeparateYCCANode : public SeparateColorNodeLegacy { - public: - SeparateYCCANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -class SeparateYUVANode : public SeparateColorNodeLegacy { - public: - SeparateYUVANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node) {} - - NodeOperation *get_color_converter(const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc deleted file mode 100644 index 6ed5b70439d..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SeparateXYZNode.h" - -#include "COM_ConvertOperation.h" - -namespace blender::compositor { - -SeparateXYZNode::SeparateXYZNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SeparateXYZNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *vector_socket = this->get_input_socket(0); - NodeOutput *output_x_socket = this->get_output_socket(0); - NodeOutput *output_y_socket = this->get_output_socket(1); - NodeOutput *output_z_socket = this->get_output_socket(2); - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(0); - converter.add_operation(operation); - converter.map_input_socket(vector_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_x_socket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(1); - converter.add_operation(operation); - converter.map_input_socket(vector_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_y_socket, operation->get_output_socket(0)); - } - - { - SeparateChannelOperation *operation = new SeparateChannelOperation(); - operation->set_channel(2); - converter.add_operation(operation); - converter.map_input_socket(vector_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_z_socket, operation->get_output_socket(0)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.h b/source/blender/compositor/nodes/COM_SeparateXYZNode.h deleted file mode 100644 index f5b69561208..00000000000 --- a/source/blender/compositor/nodes/COM_SeparateXYZNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SeparateXYZNode - * \ingroup Node - */ -class SeparateXYZNode : public Node { - public: - SeparateXYZNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.cc b/source/blender/compositor/nodes/COM_SetAlphaNode.cc deleted file mode 100644 index 001eb0dc49c..00000000000 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetAlphaNode.h" -#include "COM_SetAlphaMultiplyOperation.h" -#include "COM_SetAlphaReplaceOperation.h" - -namespace blender::compositor { - -void SetAlphaNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *editor_node = this->get_bnode(); - const NodeSetAlpha *storage = static_cast(editor_node->storage); - NodeOperation *operation = nullptr; - switch (storage->mode) { - case CMP_NODE_SETALPHA_MODE_APPLY: - operation = new SetAlphaMultiplyOperation(); - break; - case CMP_NODE_SETALPHA_MODE_REPLACE_ALPHA: - operation = new SetAlphaReplaceOperation(); - break; - } - - if (!this->get_input_socket(0)->is_linked() && this->get_input_socket(1)->is_linked()) { - operation->set_canvas_input_index(1); - } - - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h deleted file mode 100644 index 0072fd0d0d1..00000000000 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SetAlphaNode - * \ingroup Node - */ -class SetAlphaNode : public Node { - public: - SetAlphaNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cc b/source/blender/compositor/nodes/COM_SocketProxyNode.cc deleted file mode 100644 index 33731fb28d7..00000000000 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SocketProxyNode.h" - -namespace blender::compositor { - -SocketProxyNode::SocketProxyNode(bNode *editor_node, - bNodeSocket *editor_input, - bNodeSocket *editor_output, - bool use_conversion) - : Node(editor_node, false), use_conversion_(use_conversion) -{ - DataType dt; - - dt = DataType::Value; - if (editor_input->type == SOCK_RGBA) { - dt = DataType::Color; - } - if (editor_input->type == SOCK_VECTOR) { - dt = DataType::Vector; - } - this->add_input_socket(dt, editor_input); - - dt = DataType::Value; - if (editor_output->type == SOCK_RGBA) { - dt = DataType::Color; - } - if (editor_output->type == SOCK_VECTOR) { - dt = DataType::Vector; - } - this->add_output_socket(dt, editor_output); -} - -void SocketProxyNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeOperationOutput *proxy_output = converter.add_input_proxy(get_input_socket(0), - use_conversion_); - converter.map_output_socket(get_output_socket(), proxy_output); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h deleted file mode 100644 index 61bdd17a550..00000000000 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SocketProxyNode - * \ingroup Node - */ -class SocketProxyNode : public Node { - public: - SocketProxyNode(bNode *editor_node, - bNodeSocket *editor_input, - bNodeSocket *editor_output, - bool use_conversion); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; - - bool get_use_conversion() const - { - return use_conversion_; - } - void set_use_conversion(bool use_conversion) - { - use_conversion_ = use_conversion; - } - - private: - /** If true, the proxy will convert input and output data to/from the proxy socket types. */ - bool use_conversion_; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SplitNode.cc b/source/blender/compositor/nodes/COM_SplitNode.cc deleted file mode 100644 index c7d61e896c2..00000000000 --- a/source/blender/compositor/nodes/COM_SplitNode.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SplitNode.h" - -#include "COM_SplitOperation.h" - -namespace blender::compositor { - -SplitNode::SplitNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SplitNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - - SplitOperation *split_operation = new SplitOperation(); - split_operation->set_split_percentage(node->custom1); - split_operation->set_xsplit(node->custom2 == CMP_NODE_SPLIT_HORIZONTAL); - - converter.add_operation(split_operation); - converter.map_input_socket(get_input_socket(0), split_operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), split_operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), split_operation->get_output_socket(0)); - - converter.add_preview(split_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SplitNode.h b/source/blender/compositor/nodes/COM_SplitNode.h deleted file mode 100644 index 19c6345043c..00000000000 --- a/source/blender/compositor/nodes/COM_SplitNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief SplitNode - * \ingroup Node - */ -class SplitNode : public Node { - public: - SplitNode(bNode *node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.cc b/source/blender/compositor/nodes/COM_Stabilize2dNode.cc deleted file mode 100644 index 5677521f118..00000000000 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_Stabilize2dNode.h" -#include "COM_MovieClipAttributeOperation.h" -#include "COM_RotateOperation.h" -#include "COM_ScaleOperation.h" -#include "COM_SetSamplerOperation.h" -#include "COM_TranslateOperation.h" - -namespace blender::compositor { - -Stabilize2dNode::Stabilize2dNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void Stabilize2dNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - NodeInput *image_input = this->get_input_socket(0); - MovieClip *clip = (MovieClip *)editor_node->id; - bool invert = (editor_node->custom2 & CMP_NODE_STABILIZE_FLAG_INVERSE) != 0; - const PixelSampler sampler = (PixelSampler)editor_node->custom1; - - MovieClipAttributeOperation *scale_attribute = new MovieClipAttributeOperation(); - MovieClipAttributeOperation *angle_attribute = new MovieClipAttributeOperation(); - MovieClipAttributeOperation *x_attribute = new MovieClipAttributeOperation(); - MovieClipAttributeOperation *y_attribute = new MovieClipAttributeOperation(); - - scale_attribute->set_attribute(MCA_SCALE); - scale_attribute->set_framenumber(context.get_framenumber()); - scale_attribute->set_movie_clip(clip); - scale_attribute->set_invert(invert); - - angle_attribute->set_attribute(MCA_ANGLE); - angle_attribute->set_framenumber(context.get_framenumber()); - angle_attribute->set_movie_clip(clip); - angle_attribute->set_invert(invert); - - x_attribute->set_attribute(MCA_X); - x_attribute->set_framenumber(context.get_framenumber()); - x_attribute->set_movie_clip(clip); - x_attribute->set_invert(invert); - - y_attribute->set_attribute(MCA_Y); - y_attribute->set_framenumber(context.get_framenumber()); - y_attribute->set_movie_clip(clip); - y_attribute->set_invert(invert); - - converter.add_operation(scale_attribute); - converter.add_operation(angle_attribute); - converter.add_operation(x_attribute); - converter.add_operation(y_attribute); - - ScaleRelativeOperation *scale_operation = new ScaleRelativeOperation(); - scale_operation->set_sampler(sampler); - RotateOperation *rotate_operation = new RotateOperation(); - rotate_operation->set_do_degree2_rad_conversion(false); - rotate_operation->set_sampler(sampler); - TranslateOperation *translate_operation = new TranslateCanvasOperation(); - translate_operation->set_sampler(sampler); - - converter.add_operation(scale_operation); - converter.add_operation(translate_operation); - converter.add_operation(rotate_operation); - - converter.add_link(scale_attribute->get_output_socket(), scale_operation->get_input_socket(1)); - converter.add_link(scale_attribute->get_output_socket(), scale_operation->get_input_socket(2)); - - converter.add_link(angle_attribute->get_output_socket(), rotate_operation->get_input_socket(1)); - - converter.add_link(x_attribute->get_output_socket(), translate_operation->get_input_socket(1)); - converter.add_link(y_attribute->get_output_socket(), translate_operation->get_input_socket(2)); - - NodeOperationInput *stabilization_socket = nullptr; - if (invert) { - /* Translate -> Rotate -> Scale. */ - stabilization_socket = translate_operation->get_input_socket(0); - converter.map_input_socket(image_input, translate_operation->get_input_socket(0)); - - converter.add_link(translate_operation->get_output_socket(), - rotate_operation->get_input_socket(0)); - converter.add_link(rotate_operation->get_output_socket(), - scale_operation->get_input_socket(0)); - - converter.map_output_socket(get_output_socket(), scale_operation->get_output_socket()); - } - else { - /* Scale -> Rotate -> Translate. */ - stabilization_socket = scale_operation->get_input_socket(0); - converter.map_input_socket(image_input, scale_operation->get_input_socket(0)); - - converter.add_link(scale_operation->get_output_socket(), - rotate_operation->get_input_socket(0)); - converter.add_link(rotate_operation->get_output_socket(), - translate_operation->get_input_socket(0)); - - converter.map_output_socket(get_output_socket(), translate_operation->get_output_socket()); - } - - x_attribute->set_socket_input_resolution_for_stabilization(stabilization_socket); - y_attribute->set_socket_input_resolution_for_stabilization(stabilization_socket); - scale_attribute->set_socket_input_resolution_for_stabilization(stabilization_socket); - angle_attribute->set_socket_input_resolution_for_stabilization(stabilization_socket); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h deleted file mode 100644 index b6d3918b138..00000000000 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief Stabilize2dNode - * \ingroup Node - */ -class Stabilize2dNode : public Node { - public: - Stabilize2dNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.cc b/source/blender/compositor/nodes/COM_SunBeamsNode.cc deleted file mode 100644 index 89ee7a02041..00000000000 --- a/source/blender/compositor/nodes/COM_SunBeamsNode.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SunBeamsNode.h" -#include "COM_SunBeamsOperation.h" - -namespace blender::compositor { - -SunBeamsNode::SunBeamsNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SunBeamsNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input_socket = this->get_input_socket(0); - NodeOutput *output_socket = this->get_output_socket(0); - const NodeSunBeams *data = (const NodeSunBeams *)get_bnode()->storage; - - SunBeamsOperation *operation = new SunBeamsOperation(); - operation->set_data(*data); - converter.add_operation(operation); - - converter.map_input_socket(input_socket, operation->get_input_socket(0)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.h b/source/blender/compositor/nodes/COM_SunBeamsNode.h deleted file mode 100644 index 27a74550272..00000000000 --- a/source/blender/compositor/nodes/COM_SunBeamsNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief SunBeamsNode - * \ingroup Node - */ -class SunBeamsNode : public Node { - public: - SunBeamsNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SwitchNode.cc b/source/blender/compositor/nodes/COM_SwitchNode.cc deleted file mode 100644 index 31832a8ef62..00000000000 --- a/source/blender/compositor/nodes/COM_SwitchNode.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SwitchNode.h" - -namespace blender::compositor { - -SwitchNode::SwitchNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SwitchNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - bool condition = this->get_bnode()->custom1; - - NodeOperationOutput *result; - if (!condition) { - result = converter.add_input_proxy(get_input_socket(0), false); - } - else { - result = converter.add_input_proxy(get_input_socket(1), false); - } - - converter.map_output_socket(get_output_socket(0), result); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h deleted file mode 100644 index 8a76b3b1707..00000000000 --- a/source/blender/compositor/nodes/COM_SwitchNode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief SwitchNode - * \ingroup Node - */ -class SwitchNode : public Node { - public: - SwitchNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.cc b/source/blender/compositor/nodes/COM_SwitchViewNode.cc deleted file mode 100644 index f953e76dce9..00000000000 --- a/source/blender/compositor/nodes/COM_SwitchViewNode.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2015 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SwitchViewNode.h" - -namespace blender::compositor { - -SwitchViewNode::SwitchViewNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void SwitchViewNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - NodeOperationOutput *result; - const char *view_name = context.get_view_name(); - const bNode *bnode = this->get_bnode(); - - /* get the internal index of the socket with a matching name */ - int nr = BLI_findstringindex(&bnode->inputs, view_name, offsetof(bNodeSocket, name)); - nr = std::max(nr, 0); - - result = converter.add_input_proxy(get_input_socket(nr), false); - converter.map_output_socket(get_output_socket(0), result); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.h b/source/blender/compositor/nodes/COM_SwitchViewNode.h deleted file mode 100644 index 4163fa35156..00000000000 --- a/source/blender/compositor/nodes/COM_SwitchViewNode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2015 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief SwitchViewNode - * \ingroup Node - */ -class SwitchViewNode : public Node { - public: - SwitchViewNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TextureNode.cc b/source/blender/compositor/nodes/COM_TextureNode.cc deleted file mode 100644 index d93b04f5344..00000000000 --- a/source/blender/compositor/nodes/COM_TextureNode.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TextureNode.h" -#include "COM_TextureOperation.h" - -namespace blender::compositor { - -TextureNode::TextureNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void TextureNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - Tex *texture = (Tex *)editor_node->id; - TextureOperation *operation = new TextureOperation(); - bool scene_color_manage = !STREQ(context.get_scene()->display_settings.display_device, "None"); - operation->set_texture(texture); - operation->set_render_data(context.get_render_data()); - operation->set_scene_color_manage(scene_color_manage); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(1), operation->get_output_socket()); - - converter.add_preview(operation->get_output_socket()); - - TextureAlphaOperation *alpha_operation = new TextureAlphaOperation(); - alpha_operation->set_texture(texture); - alpha_operation->set_render_data(context.get_render_data()); - alpha_operation->set_scene_color_manage(scene_color_manage); - converter.add_operation(alpha_operation); - - converter.map_input_socket(get_input_socket(0), alpha_operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), alpha_operation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(0), alpha_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TextureNode.h b/source/blender/compositor/nodes/COM_TextureNode.h deleted file mode 100644 index d4b9fb29284..00000000000 --- a/source/blender/compositor/nodes/COM_TextureNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief TextureNode - * \ingroup Node - */ -class TextureNode : public Node { - public: - TextureNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TimeNode.cc b/source/blender/compositor/nodes/COM_TimeNode.cc deleted file mode 100644 index c34642041d3..00000000000 --- a/source/blender/compositor/nodes/COM_TimeNode.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TimeNode.h" - -#include "COM_SetValueOperation.h" - -#include "BKE_colortools.hh" - -namespace blender::compositor { - -TimeNode::TimeNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void TimeNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - SetValueOperation *operation = new SetValueOperation(); - const bNode *node = this->get_bnode(); - - /* stack order output: fac */ - float fac = 0.0f; - const int framenumber = context.get_framenumber(); - - if (framenumber < node->custom1) { - fac = 0.0f; - } - else if (framenumber > node->custom2) { - fac = 1.0f; - } - else if (node->custom1 < node->custom2) { - fac = (context.get_framenumber() - node->custom1) / float(node->custom2 - node->custom1); - } - - BKE_curvemapping_init((CurveMapping *)node->storage); - fac = BKE_curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac); - operation->set_value(clamp_f(fac, 0.0f, 1.0f)); - converter.add_operation(operation); - - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h deleted file mode 100644 index 8a66cb8e8c3..00000000000 --- a/source/blender/compositor/nodes/COM_TimeNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief TimeNode - * \ingroup Node - */ -class TimeNode : public Node { - public: - TimeNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cc b/source/blender/compositor/nodes/COM_TonemapNode.cc deleted file mode 100644 index ada4e101607..00000000000 --- a/source/blender/compositor/nodes/COM_TonemapNode.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TonemapNode.h" -#include "COM_TonemapOperation.h" - -namespace blender::compositor { - -TonemapNode::TonemapNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void TonemapNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const NodeTonemap *data = (const NodeTonemap *)this->get_bnode()->storage; - - TonemapOperation *operation = data->type == 1 ? new PhotoreceptorTonemapOperation() : - new TonemapOperation(); - operation->set_data(data); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h deleted file mode 100644 index 49bcf465f9a..00000000000 --- a/source/blender/compositor/nodes/COM_TonemapNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief TonemapNode - * \ingroup Node - */ -class TonemapNode : public Node { - public: - TonemapNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.cc b/source/blender/compositor/nodes/COM_TrackPositionNode.cc deleted file mode 100644 index 18a59b59688..00000000000 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TrackPositionNode.h" - -#include "COM_ConvertOperation.h" -#include "COM_TrackPositionOperation.h" - -#include "DNA_movieclip_types.h" - -#include "BKE_node.hh" - -namespace blender::compositor { - -TrackPositionNode::TrackPositionNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -static TrackPositionOperation *create_motion_operation(NodeConverter &converter, - MovieClip *clip, - NodeTrackPosData *trackpos_data, - int axis, - int frame_number, - int delta) -{ - TrackPositionOperation *operation = new TrackPositionOperation(); - operation->set_movie_clip(clip); - operation->set_tracking_object(trackpos_data->tracking_object); - operation->set_track_name(trackpos_data->track_name); - operation->set_framenumber(frame_number); - operation->set_axis(axis); - operation->set_position(CMP_NODE_TRACK_POSITION_ABSOLUTE); - operation->set_relative_frame(frame_number + delta); - operation->set_speed_output(true); - converter.add_operation(operation); - return operation; -} - -void TrackPositionNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - MovieClip *clip = (MovieClip *)editor_node->id; - NodeTrackPosData *trackpos_data = (NodeTrackPosData *)editor_node->storage; - - NodeOutput *outputX = this->get_output_socket(0); - NodeOutput *outputY = this->get_output_socket(1); - NodeOutput *output_speed = this->get_output_socket(2); - - int frame_number; - if (editor_node->custom1 == CMP_NODE_TRACK_POSITION_ABSOLUTE_FRAME) { - frame_number = editor_node->custom2; - } - else { - frame_number = context.get_framenumber(); - } - - TrackPositionOperation *operationX = new TrackPositionOperation(); - operationX->set_movie_clip(clip); - operationX->set_tracking_object(trackpos_data->tracking_object); - operationX->set_track_name(trackpos_data->track_name); - operationX->set_framenumber(frame_number); - operationX->set_axis(0); - operationX->set_position(static_cast(editor_node->custom1)); - operationX->set_relative_frame(editor_node->custom2); - converter.add_operation(operationX); - converter.map_output_socket(outputX, operationX->get_output_socket()); - - TrackPositionOperation *operationY = new TrackPositionOperation(); - operationY->set_movie_clip(clip); - operationY->set_tracking_object(trackpos_data->tracking_object); - operationY->set_track_name(trackpos_data->track_name); - operationY->set_framenumber(frame_number); - operationY->set_axis(1); - operationY->set_position(static_cast(editor_node->custom1)); - operationY->set_relative_frame(editor_node->custom2); - converter.add_operation(operationY); - converter.map_output_socket(outputY, operationY->get_output_socket()); - - TrackPositionOperation *operationMotionPreX = create_motion_operation( - converter, clip, trackpos_data, 0, frame_number, -1); - TrackPositionOperation *operationMotionPreY = create_motion_operation( - converter, clip, trackpos_data, 1, frame_number, -1); - TrackPositionOperation *operationMotionPostX = create_motion_operation( - converter, clip, trackpos_data, 0, frame_number, 1); - TrackPositionOperation *operationMotionPostY = create_motion_operation( - converter, clip, trackpos_data, 1, frame_number, 1); - - CombineChannelsOperation *combine_operation = new CombineChannelsOperation(); - converter.add_operation(combine_operation); - converter.add_link(operationMotionPreX->get_output_socket(), - combine_operation->get_input_socket(0)); - converter.add_link(operationMotionPreY->get_output_socket(), - combine_operation->get_input_socket(1)); - converter.add_link(operationMotionPostX->get_output_socket(), - combine_operation->get_input_socket(2)); - converter.add_link(operationMotionPostY->get_output_socket(), - combine_operation->get_input_socket(3)); - converter.map_output_socket(output_speed, combine_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.h b/source/blender/compositor/nodes/COM_TrackPositionNode.h deleted file mode 100644 index 068d76cd233..00000000000 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief TrackPositionNode - * \ingroup Node - */ -class TrackPositionNode : public Node { - public: - TrackPositionNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TransformNode.cc b/source/blender/compositor/nodes/COM_TransformNode.cc deleted file mode 100644 index 18d65213a46..00000000000 --- a/source/blender/compositor/nodes/COM_TransformNode.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TransformNode.h" -#include "COM_RotateOperation.h" -#include "COM_ScaleOperation.h" -#include "COM_SetSamplerOperation.h" -#include "COM_TranslateOperation.h" - -namespace blender::compositor { - -TransformNode::TransformNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void TransformNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *image_input = this->get_input_socket(0); - NodeInput *x_input = this->get_input_socket(1); - NodeInput *y_input = this->get_input_socket(2); - NodeInput *angle_input = this->get_input_socket(3); - NodeInput *scale_input = this->get_input_socket(4); - - ScaleRelativeOperation *scale_operation = new ScaleRelativeOperation(); - converter.add_operation(scale_operation); - - RotateOperation *rotate_operation = new RotateOperation(); - rotate_operation->set_do_degree2_rad_conversion(false); - converter.add_operation(rotate_operation); - - TranslateOperation *translate_operation = new TranslateCanvasOperation(); - converter.add_operation(translate_operation); - - PixelSampler sampler = (PixelSampler)this->get_bnode()->custom1; - scale_operation->set_sampler(sampler); - rotate_operation->set_sampler(sampler); - translate_operation->set_sampler(sampler); - - converter.map_input_socket(image_input, scale_operation->get_input_socket(0)); - converter.map_input_socket(scale_input, scale_operation->get_input_socket(1)); - converter.map_input_socket(scale_input, - scale_operation->get_input_socket(2)); // xscale = yscale - - converter.add_link(scale_operation->get_output_socket(), rotate_operation->get_input_socket(0)); - converter.map_input_socket(angle_input, rotate_operation->get_input_socket(1)); - - converter.add_link(rotate_operation->get_output_socket(), - translate_operation->get_input_socket(0)); - converter.map_input_socket(x_input, translate_operation->get_input_socket(1)); - converter.map_input_socket(y_input, translate_operation->get_input_socket(2)); - - converter.map_output_socket(get_output_socket(), translate_operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h deleted file mode 100644 index afca745eecd..00000000000 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief TransformNode - * \ingroup Node - */ -class TransformNode : public Node { - public: - TransformNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cc b/source/blender/compositor/nodes/COM_TranslateNode.cc deleted file mode 100644 index 955e4fde9fc..00000000000 --- a/source/blender/compositor/nodes/COM_TranslateNode.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TranslateNode.h" - -#include "COM_TranslateOperation.h" - -namespace blender::compositor { - -TranslateNode::TranslateNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void TranslateNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *bnode = this->get_bnode(); - const NodeTranslateData *data = (const NodeTranslateData *)bnode->storage; - - NodeInput *input_socket = this->get_input_socket(0); - NodeInput *input_xsocket = this->get_input_socket(1); - NodeInput *input_ysocket = this->get_input_socket(2); - NodeOutput *output_socket = this->get_output_socket(0); - - TranslateCanvasOperation *operation = new TranslateCanvasOperation(); - operation->set_wrapping(data->wrap_axis); - operation->set_is_relative(data->relative); - - switch (data->interpolation) { - case CMP_NODE_INTERPOLATION_NEAREST: - operation->set_sampler(PixelSampler::Nearest); - break; - case CMP_NODE_INTERPOLATION_BILINEAR: - operation->set_sampler(PixelSampler::Bilinear); - break; - case CMP_NODE_INTERPOLATION_BICUBIC: - operation->set_sampler(PixelSampler::Bicubic); - break; - } - - converter.add_operation(operation); - converter.map_input_socket(input_xsocket, operation->get_input_socket(1)); - converter.map_input_socket(input_ysocket, operation->get_input_socket(2)); - converter.map_output_socket(output_socket, operation->get_output_socket(0)); - converter.map_input_socket(input_socket, operation->get_input_socket(0)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h deleted file mode 100644 index b407ad49e71..00000000000 --- a/source/blender/compositor/nodes/COM_TranslateNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief TranslateNode - * \ingroup Node - */ -class TranslateNode : public Node { - public: - TranslateNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ValueNode.cc b/source/blender/compositor/nodes/COM_ValueNode.cc deleted file mode 100644 index 7ce2c29705e..00000000000 --- a/source/blender/compositor/nodes/COM_ValueNode.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ValueNode.h" -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -ValueNode::ValueNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ValueNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - SetValueOperation *operation = new SetValueOperation(); - NodeOutput *output = this->get_output_socket(0); - operation->set_value(output->get_editor_value_float()); - converter.add_operation(operation); - - converter.map_output_socket(output, operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h deleted file mode 100644 index c8b185738c5..00000000000 --- a/source/blender/compositor/nodes/COM_ValueNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ValueNode - * \ingroup Node - */ -class ValueNode : public Node { - public: - ValueNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cc b/source/blender/compositor/nodes/COM_VectorBlurNode.cc deleted file mode 100644 index 9cb9b3fc8b8..00000000000 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_VectorBlurNode.h" -#include "COM_VectorBlurOperation.h" - -namespace blender::compositor { - -VectorBlurNode::VectorBlurNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void VectorBlurNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - const bNode *node = this->get_bnode(); - const NodeBlurData *vector_blur_settings = (const NodeBlurData *)node->storage; - - VectorBlurOperation *operation = new VectorBlurOperation(); - operation->set_vector_blur_settings(vector_blur_settings); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h deleted file mode 100644 index 579b306e914..00000000000 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief VectorBlurNode - * \ingroup Node - */ -class VectorBlurNode : public Node { - public: - VectorBlurNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.cc b/source/blender/compositor/nodes/COM_VectorCurveNode.cc deleted file mode 100644 index b5907b0df8b..00000000000 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_VectorCurveNode.h" -#include "COM_VectorCurveOperation.h" - -namespace blender::compositor { - -VectorCurveNode::VectorCurveNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void VectorCurveNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - VectorCurveOperation *operation = new VectorCurveOperation(); - operation->set_curve_mapping((const CurveMapping *)this->get_bnode()->storage); - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h deleted file mode 100644 index fd8386e4ed5..00000000000 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief VectorCurveNode - * \ingroup Node - */ -class VectorCurveNode : public Node { - public: - VectorCurveNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cc b/source/blender/compositor/nodes/COM_ViewLevelsNode.cc deleted file mode 100644 index 8670de04bc2..00000000000 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ViewLevelsNode.h" -#include "COM_CalculateStandardDeviationOperation.h" - -namespace blender::compositor { - -ViewLevelsNode::ViewLevelsNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ViewLevelsNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - NodeInput *input = this->get_input_socket(0); - if (input->is_linked()) { - /* Add preview to input-socket. */ - - /* calculate mean operation */ - { - CalculateMeanOperation *operation = new CalculateMeanOperation(); - operation->set_setting(this->get_bnode()->custom1); - - converter.add_operation(operation); - converter.map_input_socket(input, operation->get_input_socket(0)); - converter.map_output_socket(this->get_output_socket(0), operation->get_output_socket()); - } - - /* calculate standard deviation operation */ - { - CalculateStandardDeviationOperation *operation = new CalculateStandardDeviationOperation(); - operation->set_setting(this->get_bnode()->custom1); - - converter.add_operation(operation); - converter.map_input_socket(input, operation->get_input_socket(0)); - converter.map_output_socket(this->get_output_socket(1), operation->get_output_socket()); - } - } - else { - converter.add_output_value(get_output_socket(0), 0.0f); - converter.add_output_value(get_output_socket(1), 0.0f); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h deleted file mode 100644 index 115aea9e61c..00000000000 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ViewLevelsNode - * \ingroup Node - */ -class ViewLevelsNode : public Node { - public: - ViewLevelsNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cc b/source/blender/compositor/nodes/COM_ViewerNode.cc deleted file mode 100644 index 830a19fe9e0..00000000000 --- a/source/blender/compositor/nodes/COM_ViewerNode.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ViewerNode.h" - -#include "COM_ViewerOperation.h" - -namespace blender::compositor { - -ViewerNode::ViewerNode(bNode *editor_node) : Node(editor_node) -{ - /* pass */ -} - -void ViewerNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const -{ - const bNode *editor_node = this->get_bnode(); - bool is_active = (editor_node->flag & NODE_DO_OUTPUT_RECALC || context.is_rendering()) && - (editor_node->flag & NODE_DO_OUTPUT); - bool ignore_alpha = (editor_node->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0; - - NodeInput *image_socket = this->get_input_socket(0); - NodeInput *alpha_socket = this->get_input_socket(1); - Image *image = (Image *)this->get_bnode()->id; - ImageUser *image_user = (ImageUser *)this->get_bnode()->storage; - ViewerOperation *viewer_operation = new ViewerOperation(); - viewer_operation->set_bnodetree(context.get_bnodetree()); - viewer_operation->set_image(image); - viewer_operation->set_image_user(image_user); - /* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */ - viewer_operation->set_use_alpha_input(ignore_alpha || alpha_socket->is_linked()); - viewer_operation->set_render_data(context.get_render_data()); - viewer_operation->set_view_name(context.get_view_name()); - - Scene *scene = context.get_scene(); - viewer_operation->set_view_settings(&scene->view_settings); - viewer_operation->set_display_settings(&scene->display_settings); - - viewer_operation->set_canvas_input_index(0); - if (!image_socket->is_linked()) { - if (alpha_socket->is_linked()) { - viewer_operation->set_canvas_input_index(1); - } - } - - converter.add_operation(viewer_operation); - converter.map_input_socket(image_socket, viewer_operation->get_input_socket(0)); - /* only use alpha link if "use alpha" is enabled */ - if (ignore_alpha) { - converter.add_input_value(viewer_operation->get_input_socket(1), 1.0f); - } - else { - converter.map_input_socket(alpha_socket, viewer_operation->get_input_socket(1)); - } - - converter.add_node_input_preview(image_socket); - - if (is_active) { - converter.register_viewer(viewer_operation); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h deleted file mode 100644 index 6fea2e8f581..00000000000 --- a/source/blender/compositor/nodes/COM_ViewerNode.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief ViewerNode - * \ingroup Node - */ -class ViewerNode : public Node { - public: - ViewerNode(bNode *editor_node); - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cc b/source/blender/compositor/nodes/COM_ZCombineNode.cc deleted file mode 100644 index ed79727b7cd..00000000000 --- a/source/blender/compositor/nodes/COM_ZCombineNode.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ZCombineNode.h" - -#include "COM_MathBaseOperation.h" -#include "COM_SMAAOperation.h" -#include "COM_ZCombineOperation.h" - -namespace blender::compositor { - -void ZCombineNode::convert_to_operations(NodeConverter &converter, - const CompositorContext & /*context*/) const -{ - if (this->get_bnode()->custom2) { - ZCombineOperation *operation = nullptr; - if (this->get_bnode()->custom1) { - operation = new ZCombineAlphaOperation(); - } - else { - operation = new ZCombineOperation(); - } - converter.add_operation(operation); - - converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(1), operation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), operation->get_input_socket(2)); - converter.map_input_socket(get_input_socket(3), operation->get_input_socket(3)); - converter.map_output_socket(get_output_socket(0), operation->get_output_socket()); - - MathMinimumOperation *zoperation = new MathMinimumOperation(); - converter.add_operation(zoperation); - - converter.map_input_socket(get_input_socket(1), zoperation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(3), zoperation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(1), zoperation->get_output_socket()); - } - else { - /* XXX custom1 is "use_alpha", what on earth is this supposed to do here?!? */ - /* not full anti alias, use masking for Z combine. be aware it uses anti aliasing. */ - - /* Step 1 create mask. */ - NodeOperation *maskoperation; - if (this->get_bnode()->custom1) { - maskoperation = new MathGreaterThanOperation(); - } - else { - maskoperation = new MathLessThanOperation(); - } - converter.add_operation(maskoperation); - - converter.map_input_socket(get_input_socket(1), maskoperation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(3), maskoperation->get_input_socket(1)); - - /* Step 2 anti alias mask bit of an expensive operation, but does the trick. */ - SMAAOperation *smaa_operation = new SMAAOperation(); - converter.add_operation(smaa_operation); - - converter.add_link(maskoperation->get_output_socket(), smaa_operation->get_input_socket(0)); - - /* use mask to blend between the input colors. */ - ZCombineMaskOperation *zcombineoperation = this->get_bnode()->custom1 ? - new ZCombineMaskAlphaOperation() : - new ZCombineMaskOperation(); - converter.add_operation(zcombineoperation); - - converter.add_link(smaa_operation->get_output_socket(), - zcombineoperation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(0), zcombineoperation->get_input_socket(1)); - converter.map_input_socket(get_input_socket(2), zcombineoperation->get_input_socket(2)); - converter.map_output_socket(get_output_socket(0), zcombineoperation->get_output_socket()); - - MathMinimumOperation *zoperation = new MathMinimumOperation(); - converter.add_operation(zoperation); - - converter.map_input_socket(get_input_socket(1), zoperation->get_input_socket(0)); - converter.map_input_socket(get_input_socket(3), zoperation->get_input_socket(1)); - converter.map_output_socket(get_output_socket(1), zoperation->get_output_socket()); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h deleted file mode 100644 index f345a65d14b..00000000000 --- a/source/blender/compositor/nodes/COM_ZCombineNode.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_Node.h" - -namespace blender::compositor { - -/** - * \brief ZCombineNode - * \ingroup Node - */ -class ZCombineNode : public Node { - public: - ZCombineNode(bNode *editor_node) : Node(editor_node) {} - void convert_to_operations(NodeConverter &converter, - const CompositorContext &context) const override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc deleted file mode 100644 index 73377835370..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_AlphaOverKeyOperation.h" - -namespace blender::compositor { - -AlphaOverKeyOperation::AlphaOverKeyOperation() -{ - flags_.can_be_constant = true; -} - -void AlphaOverKeyOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *color1 = p.color1; - const float *over_color = p.color2; - const float value = *p.value; - - if (over_color[3] <= 0.0f) { - copy_v4_v4(p.out, color1); - } - else if (value == 1.0f && over_color[3] >= 1.0f) { - copy_v4_v4(p.out, over_color); - } - else { - const float premul = value * over_color[3]; - const float mul = 1.0f - premul; - - p.out[0] = (mul * color1[0]) + premul * over_color[0]; - p.out[1] = (mul * color1[1]) + premul * over_color[1]; - p.out[2] = (mul * color1[2]) + premul * over_color[2]; - p.out[3] = (mul * color1[3]) + value * over_color[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h deleted file mode 100644 index 2dd87f33963..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MixOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class AlphaOverKeyOperation : public MixBaseOperation { - public: - AlphaOverKeyOperation(); - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc deleted file mode 100644 index 8d9e8b94bea..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_AlphaOverMixedOperation.h" - -namespace blender::compositor { - -AlphaOverMixedOperation::AlphaOverMixedOperation() -{ - x_ = 0.0f; - flags_.can_be_constant = true; -} - -void AlphaOverMixedOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *color1 = p.color1; - const float *over_color = p.color2; - const float value = *p.value; - - if (over_color[3] <= 0.0f) { - copy_v4_v4(p.out, color1); - } - else if (value == 1.0f && over_color[3] >= 1.0f) { - copy_v4_v4(p.out, over_color); - } - else { - const float addfac = 1.0f - x_ + over_color[3] * x_; - const float premul = value * addfac; - const float mul = 1.0f - value * over_color[3]; - - p.out[0] = (mul * color1[0]) + premul * over_color[0]; - p.out[1] = (mul * color1[1]) + premul * over_color[1]; - p.out[2] = (mul * color1[2]) + premul * over_color[2]; - p.out[3] = (mul * color1[3]) + value * over_color[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h deleted file mode 100644 index d03c42eb305..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MixOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class AlphaOverMixedOperation : public MixBaseOperation { - private: - float x_; - - public: - /** - * Default constructor - */ - AlphaOverMixedOperation(); - - void setX(float x) - { - x_ = x; - } - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc deleted file mode 100644 index f7169f68b09..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_AlphaOverPremultiplyOperation.h" - -namespace blender::compositor { - -AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation() -{ - flags_.can_be_constant = true; -} - -void AlphaOverPremultiplyOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *color1 = p.color1; - const float *over_color = p.color2; - const float value = *p.value; - - /* Zero alpha values should still permit an add of RGB data. */ - if (over_color[3] < 0.0f) { - copy_v4_v4(p.out, color1); - } - else if (value == 1.0f && over_color[3] >= 1.0f) { - copy_v4_v4(p.out, over_color); - } - else { - const float mul = 1.0f - value * over_color[3]; - - p.out[0] = (mul * color1[0]) + value * over_color[0]; - p.out[1] = (mul * color1[1]) + value * over_color[1]; - p.out[2] = (mul * color1[2]) + value * over_color[2]; - p.out[3] = (mul * color1[3]) + value * over_color[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h deleted file mode 100644 index f55207394c5..00000000000 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MixOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class AlphaOverPremultiplyOperation : public MixBaseOperation { - public: - AlphaOverPremultiplyOperation(); - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc deleted file mode 100644 index 5eb46dbca32..00000000000 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BilateralBlurOperation.h" - -namespace blender::compositor { - -BilateralBlurOperation::BilateralBlurOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void BilateralBlurOperation::get_area_of_interest(const int /*input_idx*/, - const rcti &output_area, - rcti &r_input_area) -{ - const int add = radius_ + 1; - - r_input_area.xmax = output_area.xmax + (add); - r_input_area.xmin = output_area.xmin - (add); - r_input_area.ymax = output_area.ymax + (add); - r_input_area.ymin = output_area.ymin - (add); -} - -struct PixelCursor { - MemoryBuffer *input_determinator; - MemoryBuffer *input_color; - int step; - float sigma_color; - const float *determ_reference_color; - float temp_color[4]; - float *out; - int radius; - int x; - int y; -}; - -static void blur_pixel(PixelCursor &p) -{ - float blur_divider = 0.0f; - zero_v4(p.out); - - /* TODO(sergey): This isn't really good bilateral filter, it should be - * using gaussian bell for weights. Also sigma_color doesn't seem to be - * used correct at all. - */ - for (int yi = -p.radius; yi <= p.radius; yi += p.step) { - for (int xi = -p.radius; xi <= p.radius; xi += p.step) { - p.input_determinator->read_elem_clamped(p.x + xi, p.y + yi, p.temp_color); - /* Do not take the alpha channel into account. */ - const float delta_color = (fabsf(p.determ_reference_color[0] - p.temp_color[0]) + - fabsf(p.determ_reference_color[1] - p.temp_color[1]) + - fabsf(p.determ_reference_color[2] - p.temp_color[2])); - if (delta_color < p.sigma_color) { - /* Add this to the blur. */ - p.input_color->read_elem_clamped(p.x + xi, p.y + yi, p.temp_color); - add_v4_v4(p.out, p.temp_color); - blur_divider += 1.0f; - } - } - } - - if (blur_divider > 0.0f) { - mul_v4_fl(p.out, 1.0f / blur_divider); - } - else { - copy_v4_v4(p.out, COM_COLOR_BLACK); - } -} - -void BilateralBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - PixelCursor p = {}; - p.step = 1; - p.sigma_color = data_->sigma_color; - p.radius = radius_; - p.input_color = inputs[0]; - p.input_determinator = inputs[1]; - for (int y = area.ymin; y < area.ymax; y++) { - p.out = output->get_elem(area.xmin, y); - p.y = y; - for (int x = area.xmin; x < area.xmax; x++) { - p.x = x; - /* This will be used as the reference color for the determinator. */ - p.determ_reference_color = p.input_determinator->get_elem(x, y); - blur_pixel(p); - p.out += output->elem_stride; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.h b/source/blender/compositor/operations/COM_BilateralBlurOperation.h deleted file mode 100644 index fb4437d8d7c..00000000000 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_math_base.hh" - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BilateralBlurOperation : public MultiThreadedOperation { - private: - NodeBilateralBlurData *data_; - int radius_; - - public: - BilateralBlurOperation(); - - void set_data(NodeBilateralBlurData *data) - { - data_ = data; - radius_ = int(math::ceil(data->sigma_space + data->iter)); - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cc b/source/blender/compositor/operations/COM_BlurBaseOperation.cc deleted file mode 100644 index 8231c907763..00000000000 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cc +++ /dev/null @@ -1,200 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BlurBaseOperation.h" -#include "COM_ConstantOperation.h" - -#include "RE_pipeline.h" - -namespace blender::compositor { - -BlurBaseOperation::BlurBaseOperation(DataType data_type) -{ - /* data_type is almost always DataType::Color except for alpha-blur */ - this->add_input_socket(data_type); - this->add_input_socket(DataType::Value); - this->add_output_socket(data_type); - flags_.can_be_constant = true; - memset(&data_, 0, sizeof(NodeBlurData)); - size_ = 1.0f; - sizeavailable_ = false; - extend_bounds_ = false; - use_variable_size_ = false; -} - -void BlurBaseOperation::init_data() -{ - update_size(); - - data_.image_in_width = this->get_width(); - data_.image_in_height = this->get_height(); - if (data_.relative) { - int sizex, sizey; - switch (data_.aspect) { - case CMP_NODE_BLUR_ASPECT_Y: - sizex = sizey = data_.image_in_width; - break; - case CMP_NODE_BLUR_ASPECT_X: - sizex = sizey = data_.image_in_height; - break; - default: - BLI_assert(data_.aspect == CMP_NODE_BLUR_ASPECT_NONE); - sizex = data_.image_in_width; - sizey = data_.image_in_height; - break; - } - data_.sizex = round_fl_to_int(data_.percentx * 0.01f * sizex); - data_.sizey = round_fl_to_int(data_.percenty * 0.01f * sizey); - } -} - -float *BlurBaseOperation::make_gausstab(float rad, int size) -{ - float *gausstab, sum, val; - int i, n; - - n = 2 * size + 1; - - gausstab = (float *)MEM_mallocN(sizeof(float) * n, __func__); - - sum = 0.0f; - float fac = (rad > 0.0f ? 1.0f / rad : 0.0f); - for (i = -size; i <= size; i++) { - val = RE_filter_value(data_.filtertype, float(i) * fac); - sum += val; - gausstab[i + size] = val; - } - - sum = 1.0f / sum; - for (i = 0; i < n; i++) { - gausstab[i] *= sum; - } - - return gausstab; -} - -#if BLI_HAVE_SSE2 -__m128 *BlurBaseOperation::convert_gausstab_sse(const float *gausstab, int size) -{ - int n = 2 * size + 1; - __m128 *gausstab_sse = (__m128 *)MEM_mallocN_aligned(sizeof(__m128) * n, 16, "gausstab sse"); - for (int i = 0; i < n; i++) { - gausstab_sse[i] = _mm_set1_ps(gausstab[i]); - } - return gausstab_sse; -} -#endif - -float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff) -{ - float *dist_fac_invert, val; - int i, n; - - n = 2 * size + 1; - - dist_fac_invert = (float *)MEM_mallocN(sizeof(float) * n, __func__); - - float fac = (rad > 0.0f ? 1.0f / rad : 0.0f); - for (i = -size; i <= size; i++) { - val = 1.0f - fabsf(float(i) * fac); - - /* keep in sync with rna_enum_proportional_falloff_curve_only_items */ - switch (falloff) { - case PROP_SMOOTH: - /* ease - gives less hard lines for dilate/erode feather */ - val = (3.0f * val * val - 2.0f * val * val * val); - break; - case PROP_SPHERE: - val = sqrtf(2.0f * val - val * val); - break; - case PROP_ROOT: - val = sqrtf(val); - break; - case PROP_SHARP: - val = val * val; - break; - case PROP_INVSQUARE: - val = val * (2.0f - val); - break; - case PROP_LIN: - /* nothing to do */ - break; -#ifndef NDEBUG - case -1: - /* uninitialized! */ - BLI_assert(0); - break; -#endif - default: - /* nothing */ - break; - } - dist_fac_invert[i + size] = val; - } - - return dist_fac_invert; -} - -void BlurBaseOperation::set_data(const NodeBlurData *data) -{ - memcpy(&data_, data, sizeof(NodeBlurData)); -} - -int BlurBaseOperation::get_blur_size(eDimension dim) const -{ - switch (dim) { - case eDimension::X: - return data_.sizex; - case eDimension::Y: - return data_.sizey; - } - return -1; -} - -void BlurBaseOperation::update_size() -{ - if (sizeavailable_ || use_variable_size_) { - return; - } - - NodeOperation *size_input = get_input_operation(SIZE_INPUT_INDEX); - if (size_input->get_flags().is_constant_operation) { - size_ = *static_cast(size_input)->get_constant_elem(); - } /* Else use default. */ - sizeavailable_ = true; -} - -void BlurBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - if (!extend_bounds_) { - NodeOperation::determine_canvas(preferred_area, r_area); - return; - } - - /* Setting a modifier ensures all non main inputs have extended bounds as preferred - * canvas, avoiding unnecessary canvas conversions that would hide constant - * operations. */ - set_determined_canvas_modifier([=](rcti &canvas) { - /* Rounding to even prevents jiggling in backdrop while switching size values. */ - canvas.xmax += round_to_even(2 * size_ * data_.sizex); - canvas.ymax += round_to_even(2 * size_ * data_.sizey); - }); - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void BlurBaseOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case 0: - r_input_area = output_area; - break; - case 1: - r_input_area = use_variable_size_ ? output_area : COM_CONSTANT_INPUT_AREA_OF_INTEREST; - break; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h deleted file mode 100644 index 15fb2f172ea..00000000000 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -#define MAX_GAUSSTAB_RADIUS 30000 - -#include "BLI_simd.hh" - -namespace blender::compositor { - -class BlurBaseOperation : public MultiThreadedOperation { - private: - bool extend_bounds_; - - protected: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int SIZE_INPUT_INDEX = 1; - - protected: - BlurBaseOperation(DataType data_type8); - float *make_gausstab(float rad, int size); -#if BLI_HAVE_SSE2 - __m128 *convert_gausstab_sse(const float *gausstab, int size); -#endif - /** - * Normalized distance from the current (inverted so 1.0 is close and 0.0 is far) - * 'ease' is applied after, looks nicer. - */ - float *make_dist_fac_inverse(float rad, int size, int falloff); - - void update_size(); - - NodeBlurData data_; - - float size_; - bool sizeavailable_; - - /* Flags for inheriting classes. */ - bool use_variable_size_; - - public: - virtual void init_data() override; - - void set_data(const NodeBlurData *data); - - void set_size(float size) - { - size_ = size; - sizeavailable_ = true; - } - - void set_extend_bounds(bool extend_bounds) - { - extend_bounds_ = extend_bounds; - } - - int get_blur_size(eDimension dim) const; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - virtual void get_area_of_interest(int input_idx, - const rcti &output_area, - rcti &r_input_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cc b/source/blender/compositor/operations/COM_BokehBlurOperation.cc deleted file mode 100644 index 246a5ebf877..00000000000 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" - -#include "COM_BokehBlurOperation.h" -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -constexpr int IMAGE_INPUT_INDEX = 0; -constexpr int BOKEH_INPUT_INDEX = 1; -constexpr int BOUNDING_BOX_INPUT_INDEX = 2; -constexpr int SIZE_INPUT_INDEX = 3; - -BokehBlurOperation::BokehBlurOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; - - size_ = 1.0f; - sizeavailable_ = false; - - extend_bounds_ = false; -} - -void BokehBlurOperation::init_data() -{ - update_size(); -} - -void BokehBlurOperation::update_size() -{ - if (sizeavailable_) { - return; - } - - NodeOperation *size_input = get_input_operation(SIZE_INPUT_INDEX); - if (size_input->get_flags().is_constant_operation) { - size_ = *static_cast(size_input)->get_constant_elem(); - CLAMP(size_, 0.0f, 10.0f); - } /* Else use default. */ - sizeavailable_ = true; -} - -void BokehBlurOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - if (!extend_bounds_) { - NodeOperation::determine_canvas(preferred_area, r_area); - return; - } - - set_determined_canvas_modifier([=](rcti &canvas) { - const float max_dim = std::max(BLI_rcti_size_x(&canvas), BLI_rcti_size_y(&canvas)); - /* Rounding to even prevents image jiggling in backdrop while switching size values. */ - float add_size = round_to_even(2 * size_ * max_dim / 100.0f); - canvas.xmax += add_size; - canvas.ymax += add_size; - }); - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void BokehBlurOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: { - const float max_dim = std::max(this->get_width(), this->get_height()); - const float add_size = size_ * max_dim / 100.0f; - r_input_area.xmin = output_area.xmin - add_size; - r_input_area.xmax = output_area.xmax + add_size; - r_input_area.ymin = output_area.ymin - add_size; - r_input_area.ymax = output_area.ymax + add_size; - break; - } - case BOKEH_INPUT_INDEX: { - NodeOperation *bokeh_input = get_input_operation(BOKEH_INPUT_INDEX); - r_input_area = bokeh_input->get_canvas(); - break; - } - case BOUNDING_BOX_INPUT_INDEX: - r_input_area = output_area; - break; - case SIZE_INPUT_INDEX: { - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - break; - } - } -} - -void BokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const float max_dim = std::max(this->get_width(), this->get_height()); - const int radius = size_ * max_dim / 100.0f; - - const MemoryBuffer *image_input = inputs[IMAGE_INPUT_INDEX]; - const MemoryBuffer *bokeh_input = inputs[BOKEH_INPUT_INDEX]; - const int2 bokeh_size = int2(bokeh_input->get_width(), bokeh_input->get_height()); - MemoryBuffer *bounding_input = inputs[BOUNDING_BOX_INPUT_INDEX]; - BuffersIterator it = output->iterate_with({bounding_input}, area); - for (; !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - const float bounding_box = *it.in(0); - if (bounding_box <= 0.0f) { - image_input->read_elem(x, y, it.out); - continue; - } - - float4 accumulated_color = float4(0.0f); - float4 accumulated_weight = float4(0.0f); - for (int yi = -radius; yi <= radius; ++yi) { - for (int xi = -radius; xi <= radius; ++xi) { - const float2 normalized_texel = (float2(xi, yi) + radius + 0.5f) / (radius * 2.0f + 1.0f); - const float2 weight_texel = (1.0f - normalized_texel) * float2(bokeh_size - 1); - const float4 weight = bokeh_input->get_elem(int(weight_texel.x), int(weight_texel.y)); - const float4 color = float4(image_input->get_elem_clamped(x + xi, y + yi)) * weight; - accumulated_color += color; - accumulated_weight += weight; - } - } - - const float4 final_color = math::safe_divide(accumulated_color, accumulated_weight); - copy_v4_v4(it.out, final_color); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h deleted file mode 100644 index 85b276cf866..00000000000 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BokehBlurOperation : public MultiThreadedOperation { - private: - void update_size(); - float size_; - bool sizeavailable_; - - bool extend_bounds_; - - public: - BokehBlurOperation(); - - void init_data() override; - - void set_size(float size) - { - size_ = size; - sizeavailable_ = true; - } - - void set_extend_bounds(bool extend_bounds) - { - extend_bounds_ = extend_bounds; - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cc b/source/blender/compositor/operations/COM_BokehImageOperation.cc deleted file mode 100644 index 3332b0a284a..00000000000 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BokehImageOperation.h" - -#include "BLI_math_base.h" -#include "BLI_math_base.hh" -#include "BLI_math_numbers.hh" -#include "BLI_math_vector.hh" - -namespace blender::compositor { - -BokehImageOperation::BokehImageOperation() -{ - this->add_output_socket(DataType::Color); - delete_data_ = false; -} - -/* The exterior angle is the angle between each two consecutive vertices of the regular polygon - * from its center. */ -static float compute_exterior_angle(int sides) -{ - return (math::numbers::pi * 2.0f) / sides; -} - -static float compute_rotation(float angle, int sides) -{ - /* Offset the rotation such that the second vertex of the regular polygon lies on the positive - * y axis, which is 90 degrees minus the angle that it makes with the positive x axis assuming - * the first vertex lies on the positive x axis. */ - const float offset = math::numbers::pi / 2.0f - compute_exterior_angle(sides); - return angle - offset; -} - -void BokehImageOperation::init_execution() -{ - exterior_angle_ = compute_exterior_angle(data_->flaps); - rotation_ = compute_rotation(data_->angle, data_->flaps); - roundness_ = data_->rounding; - catadioptric_ = data_->catadioptric; - lens_shift_ = data_->lensshift; -} - -float2 BokehImageOperation::get_regular_polygon_vertex_position(int vertex_index) -{ - float angle = exterior_angle_ * vertex_index - rotation_; - return float2(math::cos(angle), math::sin(angle)); -} - -float2 BokehImageOperation::closest_point_on_line(float2 point, float2 line_start, float2 line_end) -{ - float2 line_vector = line_end - line_start; - float2 point_vector = point - line_start; - float line_length_squared = math::dot(line_vector, line_vector); - float parameter = math::dot(point_vector, line_vector) / line_length_squared; - return line_start + line_vector * parameter; -} - -float BokehImageOperation::bokeh(float2 point, float circumradius) -{ - /* Get the index of the vertex of the regular polygon whose polar angle is maximum but less than - * the polar angle of the given point, taking rotation into account. This essentially finds the - * vertex closest to the given point in the clock-wise direction. */ - float angle = floored_fmod(math::atan2(point.y, point.x) + rotation_, - math::numbers::pi_v * 2.0f); - int vertex_index = int(angle / exterior_angle_); - - /* Compute the shortest distance between the origin and the polygon edge composed from the - * previously selected vertex and the one following it. */ - float2 first_vertex = this->get_regular_polygon_vertex_position(vertex_index) * circumradius; - float2 second_vertex = this->get_regular_polygon_vertex_position(vertex_index + 1) * - circumradius; - float2 closest_point = this->closest_point_on_line(point, first_vertex, second_vertex); - float distance_to_edge = math::length(closest_point); - - /* Mix the distance to the edge with the circumradius, making it tend to the distance to a - * circle when roundness tends to 1. */ - float distance_to_edge_round = math::interpolate(distance_to_edge, circumradius, roundness_); - - /* The point is outside of the bokeh, so we return 0. */ - float distance = math::length(point); - if (distance > distance_to_edge_round) { - return 0.0f; - } - - /* The point is inside the catadioptric hole and is not part of the bokeh, so we return 0. */ - float catadioptric_distance = distance_to_edge_round * catadioptric_; - if (distance < catadioptric_distance) { - return 0.0f; - } - - /* The point is very close to the edge of the bokeh, so we return the difference between the - * distance to the edge and the distance as a form of anti-aliasing. */ - if (distance_to_edge_round - distance < 1.0f) { - return distance_to_edge_round - distance; - } - - /* The point is very close to the edge of the catadioptric hole, so we return the difference - * between the distance to the hole and the distance as a form of anti-aliasing. */ - if (catadioptric_ != 0.0f && distance - catadioptric_distance < 1.0f) { - return distance - catadioptric_distance; - } - - /* Otherwise, the point is part of the bokeh and we return 1. */ - return 1.0f; -} - -void BokehImageOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - /* Since we need the regular polygon to occupy the entirety of the output image, the circumradius - * of the regular polygon is half the width of the output image. */ - float circumradius = float(resolution_) / 2.0f; - - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - int2 texel = int2(it.x, it.y); - - /* Move the texel coordinates such that the regular polygon is centered. */ - float2 point = float2(texel) + float2(0.5f) - circumradius; - - /* Each of the color channels of the output image contains a bokeh with a different - * circumradius. The largest one occupies the whole image as stated above, while the other two - * have circumradii that are shifted by an amount that is proportional to the "lens_shift" - * value. The alpha channel of the output is the average of all three values. */ - float min_shift = math::abs(lens_shift_ * circumradius); - float min = min_shift == circumradius ? 0.0f : this->bokeh(point, circumradius - min_shift); - - float median_shift = min_shift / 2.0f; - float median = this->bokeh(point, circumradius - median_shift); - - float max = this->bokeh(point, circumradius); - float4 bokeh = float4(min, median, max, (max + median + min) / 3.0f); - - /* If the lens shift is negative, swap the min and max bokeh values, which are stored in the - * red and blue channels respectively. Note that we take the absolute value of the lens shift - * above, so the sign of the lens shift only controls this swap. */ - if (lens_shift_ < 0.0f) { - std::swap(bokeh.x, bokeh.z); - } - - copy_v4_v4(it.out, bokeh); - } -} - -void BokehImageOperation::deinit_execution() -{ - if (delete_data_) { - if (data_) { - delete data_; - data_ = nullptr; - } - } -} - -void BokehImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - BLI_rcti_init(&r_area, 0, resolution_, 0, resolution_); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h deleted file mode 100644 index debddb051ed..00000000000 --- a/source/blender/compositor/operations/COM_BokehImageOperation.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_math_vector_types.hh" - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BokehImageOperation : public MultiThreadedOperation { - private: - const NodeBokehImage *data_; - - int resolution_ = COM_BLUR_BOKEH_PIXELS; - - float exterior_angle_; - float rotation_; - float roundness_; - float catadioptric_; - float lens_shift_; - - /* See the delete_data_on_finish method. */ - bool delete_data_; - - /** - * Get the 2D vertex position of the vertex with the given index in the regular polygon - * representing this bokeh. The polygon is rotated by the rotation amount and have a unit - * circumradius. The regular polygon is one whose vertices' exterior angles are given by - * exterior_angle. See the bokeh function for more information. - */ - float2 get_regular_polygon_vertex_position(int vertex_index); - /** - * Find the closest point to the given point on the given line. This assumes the length of the - * given line is not zero. - */ - float2 closest_point_on_line(float2 point, float2 line_start, float2 line_end); - /** - * Compute the value of the bokeh at the given point. The computed bokeh is essentially a regular - * polygon centered in space having the given circumradius. The regular polygon is one whose - * vertices' exterior angles are given by "exterior_angle", which relates to the number of - * vertices n through the equation "exterior angle = 2 pi / n". The regular polygon may - * additionally morph into a shape with the given properties: - * - * - The regular polygon may have a circular hole in its center whose radius is controlled by the - * "catadioptric" value. - * - The regular polygon is rotated by the "rotation" value. - * - The regular polygon can morph into a circle controlled by the "roundness" value, - * such that it becomes a full circle at unit roundness. - * - * The function returns 0 when the point lies inside the regular polygon and 1 otherwise. - * However, at the edges, it returns a narrow band gradient as a form of anti-aliasing. - */ - float bokeh(float2 point, float circumradius); - - public: - BokehImageOperation(); - - void init_execution() override; - void deinit_execution() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_data(const NodeBokehImage *data) - { - data_ = data; - } - - void set_resolution(int resolution) - { - resolution_ = resolution; - } - - /** - * \brief delete_data_on_finish - * - * There are cases that the compositor uses this operation on its own (see defocus node) - * the delete_data_on_finish must only be called when the data has been created by the - *compositor. It should not be called when the data has been created by the node-editor/user. - */ - void delete_data_on_finish() - { - delete_data_ = true; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc deleted file mode 100644 index 523e02a4c4d..00000000000 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BoxMaskOperation.h" - -namespace blender::compositor { - -BoxMaskOperation::BoxMaskOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - cosine_ = 0.0f; - sine_ = 0.0f; -} -void BoxMaskOperation::init_execution() -{ - const double rad = double(data_->rotation); - cosine_ = cos(rad); - sine_ = sin(rad); - aspect_ratio_ = float(this->get_width()) / this->get_height(); -} - -void BoxMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MaskFunc mask_func; - switch (mask_type_) { - case CMP_NODE_MASKTYPE_ADD: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? std::max(mask[0], value[0]) : mask[0]; - }; - break; - case CMP_NODE_MASKTYPE_SUBTRACT: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? std::clamp(mask[0] - value[0], 0.0f, 1.0f) : mask[0]; - }; - break; - case CMP_NODE_MASKTYPE_MULTIPLY: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? mask[0] * value[0] : 0; - }; - break; - case CMP_NODE_MASKTYPE_NOT: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - if (is_inside) { - return mask[0] > 0.0f ? 0.0f : value[0]; - } - return mask[0]; - }; - break; - } - apply_mask(output, area, inputs, mask_func); -} - -void BoxMaskOperation::apply_mask(MemoryBuffer *output, - const rcti &area, - Span inputs, - MaskFunc mask_func) -{ - const float op_last_x = std::max(this->get_width() - 1.0f, FLT_EPSILON); - const float op_last_y = std::max(this->get_height() - 1.0f, FLT_EPSILON); - const float half_w = data_->width / 2.0f + FLT_EPSILON; - const float half_h = data_->height / 2.0f + FLT_EPSILON; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float op_ry = it.y / op_last_y; - const float dy = (op_ry - data_->y) / aspect_ratio_; - const float op_rx = it.x / op_last_x; - const float dx = op_rx - data_->x; - const float rx = data_->x + (cosine_ * dx + sine_ * dy); - const float ry = data_->y + (-sine_ * dx + cosine_ * dy); - - const bool inside = (rx >= data_->x - half_w && rx <= data_->x + half_w && - ry >= data_->y - half_h && ry <= data_->y + half_h); - const float *mask = it.in(0); - const float *value = it.in(1); - *it.out = mask_func(inside, mask, value); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h deleted file mode 100644 index 48adb764a9c..00000000000 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BoxMaskOperation : public MultiThreadedOperation { - private: - using MaskFunc = std::function; - - float sine_; - float cosine_; - float aspect_ratio_; - int mask_type_; - - const NodeBoxMask *data_; - - public: - BoxMaskOperation(); - - void init_execution() override; - - void set_data(const NodeBoxMask *data) - { - data_ = data; - } - - void set_mask_type(int mask_type) - { - mask_type_ = mask_type; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - void apply_mask(MemoryBuffer *output, - const rcti &area, - Span inputs, - MaskFunc mask_func); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cc b/source/blender/compositor/operations/COM_BrightnessOperation.cc deleted file mode 100644 index 738dda2fc35..00000000000 --- a/source/blender/compositor/operations/COM_BrightnessOperation.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_BrightnessOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -BrightnessOperation::BrightnessOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - use_premultiply_ = false; - flags_.can_be_constant = true; -} - -void BrightnessOperation::set_use_premultiply(bool use_premultiply) -{ - use_premultiply_ = use_premultiply; -} - -void BrightnessOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - float tmp_color[4]; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *in_color = it.in(0); - const float brightness = *it.in(1) / 100.0f; - const float contrast = *it.in(2); - float delta = contrast / 200.0f; - /* - * The algorithm is by Werner D. Streidt - * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV `demhist.c`. - */ - float a, b; - if (contrast > 0) { - a = 1.0f - delta * 2.0f; - a = 1.0f / max_ff(a, FLT_EPSILON); - b = a * (brightness - delta); - } - else { - delta *= -1; - a = max_ff(1.0f - delta * 2.0f, 0.0f); - b = a * brightness + delta; - } - const float *color; - if (use_premultiply_) { - premul_to_straight_v4_v4(tmp_color, in_color); - color = tmp_color; - } - else { - color = in_color; - } - it.out[0] = a * color[0] + b; - it.out[1] = a * color[1] + b; - it.out[2] = a * color[2] + b; - it.out[3] = color[3]; - if (use_premultiply_) { - straight_to_premul_v4(it.out); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h deleted file mode 100644 index 2f3d921c67d..00000000000 --- a/source/blender/compositor/operations/COM_BrightnessOperation.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BrightnessOperation : public MultiThreadedOperation { - private: - bool use_premultiply_; - - public: - BrightnessOperation(); - - void set_use_premultiply(bool use_premultiply); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc deleted file mode 100644 index fa9dc768e1d..00000000000 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc +++ /dev/null @@ -1,132 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CalculateMeanOperation.h" - -#include "COM_ExecutionSystem.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -CalculateMeanOperation::CalculateMeanOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_output_socket(DataType::Value); - is_calculated_ = false; - setting_ = 1; - - /* Prevent optimization by constant folder. */ - flags_.is_constant_operation = false; - - needs_canvas_to_get_constant_ = true; -} - -void CalculateMeanOperation::init_execution() -{ - is_calculated_ = false; -} - -void CalculateMeanOperation::set_setting(int setting) -{ - setting_ = setting; - switch (setting) { - case 1: { - setting_func_ = IMB_colormanagement_get_luminance; - break; - } - case 2: { - setting_func_ = [](const float *elem) { return elem[0]; }; - break; - } - case 3: { - setting_func_ = [](const float *elem) { return elem[1]; }; - break; - } - case 4: { - setting_func_ = [](const float *elem) { return elem[2]; }; - break; - } - case 5: { - setting_func_ = [](const float *elem) { - float yuv[3]; - rgb_to_yuv(elem[0], elem[1], elem[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709); - return yuv[0]; - }; - break; - } - } -} - -void CalculateMeanOperation::get_area_of_interest(int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - r_input_area = get_input_operation(input_idx)->get_canvas(); -} - -void CalculateMeanOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - ConstantOperation::determine_canvas(preferred_area, r_area); - r_area = preferred_area; -} - -const float *CalculateMeanOperation::get_constant_elem() -{ - /* Node de-duplication uses the constant value as part of a hash for constant operations. - * The constant is not known in advance here, but need to return something. The value does - * not really matter, because if two CalculateMean operations are connected to different - * inputs it will be handled via hash of the input subtree. */ - static float f = 0; - return &f; -} - -void CalculateMeanOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - if (!is_calculated_) { - MemoryBuffer *input = inputs[0]; - constant_value_ = calculate_value(input); - is_calculated_ = true; - } - - output->fill(area, &constant_value_); -} - -float CalculateMeanOperation::calculate_value(const MemoryBuffer *input) const -{ - return calculate_mean(input); -} - -float CalculateMeanOperation::calculate_mean(const MemoryBuffer *input) const -{ - PixelsSum total = {0}; - exec_system_->execute_work( - input->get_rect(), - [=](const rcti &split) { return calc_area_sum(input, split); }, - total, - [](PixelsSum &join, const PixelsSum &chunk) { - join.sum += chunk.sum; - join.num_pixels += chunk.num_pixels; - }); - return total.num_pixels == 0 ? 0.0f : total.sum / total.num_pixels; -} - -using PixelsSum = CalculateMeanOperation::PixelsSum; -PixelsSum CalculateMeanOperation::calc_area_sum(const MemoryBuffer *input, const rcti &area) const -{ - PixelsSum result = {0}; - for (const float *elem : input->get_buffer_area(area)) { - if (elem[3] <= 0.0f) { - continue; - } - result.sum += setting_func_(elem); - result.num_pixels++; - } - return result; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h deleted file mode 100644 index b4a4ab729fb..00000000000 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConstantOperation.h" -#include "DNA_node_types.h" -#include - -namespace blender::compositor { - -/** - * \brief base class of CalculateMean, implementing the simple CalculateMean - * \ingroup operation - */ -class CalculateMeanOperation : public ConstantOperation { - public: - struct PixelsSum { - float sum; - int num_pixels; - }; - - protected: - bool is_calculated_; - float constant_value_; - int setting_; - std::function setting_func_; - - public: - CalculateMeanOperation(); - - void init_execution() override; - - void set_setting(int setting); - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - const float *get_constant_elem() override; - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - protected: - /* Calculate value which will be written to the single-element output in the - * update_memory_buffer(). - * The caller takes care of checking the value is only calculated once. */ - virtual float calculate_value(const MemoryBuffer *input) const; - - float calculate_mean(const MemoryBuffer *input) const; - - private: - PixelsSum calc_area_sum(const MemoryBuffer *input, const rcti &area) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc deleted file mode 100644 index 31013cea35c..00000000000 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CalculateStandardDeviationOperation.h" - -#include "COM_ExecutionSystem.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -float CalculateStandardDeviationOperation::calculate_value(const MemoryBuffer *input) const -{ - const float mean = this->calculate_mean(input); - - PixelsSum total = {0}; - exec_system_->execute_work( - input->get_rect(), - [=](const rcti &split) { return this->calc_area_sum(input, split, mean); }, - total, - [](PixelsSum &join, const PixelsSum &chunk) { - join.sum += chunk.sum; - join.num_pixels += chunk.num_pixels; - }); - - return total.num_pixels <= 1 ? 0.0f : sqrt(total.sum / float(total.num_pixels - 1)); -} - -using PixelsSum = CalculateMeanOperation::PixelsSum; -PixelsSum CalculateStandardDeviationOperation::calc_area_sum(const MemoryBuffer *input, - const rcti &area, - const float mean) const -{ - PixelsSum result = {0}; - for (const float *elem : input->get_buffer_area(area)) { - if (elem[3] <= 0.0f) { - continue; - } - const float value = setting_func_(elem); - result.sum += (value - mean) * (value - mean); - result.num_pixels++; - } - return result; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h deleted file mode 100644 index 88a951cc535..00000000000 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_CalculateMeanOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief base class of CalculateStandardDeviation, - * implementing the simple CalculateStandardDeviation. - * \ingroup operation - */ -class CalculateStandardDeviationOperation : public CalculateMeanOperation { - protected: - float standard_deviation_; - - float calculate_value(const MemoryBuffer *input) const override; - - private: - PixelsSum calc_area_sum(const MemoryBuffer *input, const rcti &area, float mean) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cc b/source/blender/compositor/operations/COM_ChangeHSVOperation.cc deleted file mode 100644 index 16d51cced48..00000000000 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ChangeHSVOperation.h" - -namespace blender::compositor { - -ChangeHSVOperation::ChangeHSVOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void ChangeHSVOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - const float hue = *it.in(1); - it.out[0] = color[0] + (hue - 0.5f); - if (it.out[0] > 1.0f) { - it.out[0] -= 1.0f; - } - else if (it.out[0] < 0.0f) { - it.out[0] += 1.0f; - } - const float saturation = *it.in(2); - const float value = *it.in(3); - it.out[1] = color[1] * saturation; - it.out[2] = color[2] * value; - it.out[3] = color[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h deleted file mode 100644 index b2b81586fa3..00000000000 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ChangeHSVOperation : public MultiThreadedOperation { - public: - ChangeHSVOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc b/source/blender/compositor/operations/COM_ChannelMatteOperation.cc deleted file mode 100644 index 4d17442fcc5..00000000000 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ChannelMatteOperation.h" - -namespace blender::compositor { - -ChannelMatteOperation::ChannelMatteOperation() -{ - add_input_socket(DataType::Color); - add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -void ChannelMatteOperation::init_execution() -{ - limit_range_ = limit_max_ - limit_min_; - - switch (limit_method_) { - /* SINGLE */ - case 0: { - /* 123 / RGB / HSV / YUV / YCC */ - const int matte_channel = matte_channel_ - 1; - const int limit_channel = limit_channel_ - 1; - ids_[0] = matte_channel; - ids_[1] = limit_channel; - ids_[2] = limit_channel; - break; - } - /* MAX */ - case 1: { - switch (matte_channel_) { - case 1: { - ids_[0] = 0; - ids_[1] = 1; - ids_[2] = 2; - break; - } - case 2: { - ids_[0] = 1; - ids_[1] = 0; - ids_[2] = 2; - break; - } - case 3: { - ids_[0] = 2; - ids_[1] = 0; - ids_[2] = 1; - break; - } - default: - break; - } - break; - } - default: - break; - } -} - -void ChannelMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - - /* Matte operation. */ - float alpha = color[ids_[0]] - std::max(color[ids_[1]], color[ids_[2]]); - - /* Flip because 0.0 is transparent, not 1.0. */ - alpha = 1.0f - alpha; - - /* Test range. */ - if (alpha > limit_max_) { - alpha = color[3]; /* Whatever it was prior. */ - } - else if (alpha < limit_min_) { - alpha = 0.0f; - } - else { /* Blend. */ - alpha = (alpha - limit_min_) / limit_range_; - } - - /* Store matte(alpha) value in [0] to go with - * COM_SetAlphaMultiplyOperation and the Value output. - */ - - /* Don't make something that was more transparent less transparent. */ - *it.out = std::min(alpha, color[3]); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h deleted file mode 100644 index 5c7d05b6a53..00000000000 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ChannelMatteOperation : public MultiThreadedOperation { - private: - // int color_space_; /* node->custom1 */ /* UNUSED */ /* TODO? */ - int matte_channel_; /* node->custom2 */ - int limit_method_; /* node->algorithm */ - int limit_channel_; /* node->channel */ - float limit_max_; /* node->storage->t1 */ - float limit_min_; /* node->storage->t2 */ - - float limit_range_; - - /** - * ids to use for the operations (max and simple) - * alpha = in[ids[0]] - std::max(in[ids[1]], in[ids[2]]) - * the simple operation is using: - * alpha = in[ids[0]] - in[ids[1]] - * but to use the same formula and operation for both we do: - * ids[2] = ids[1] - * alpha = in[ids[0]] - std::max(in[ids[1]], in[ids[2]]) - */ - int ids_[3]; - - public: - ChannelMatteOperation(); - - void init_execution() override; - - void set_settings(NodeChroma *node_chroma, const int custom2) - { - limit_max_ = node_chroma->t1; - limit_min_ = node_chroma->t2; - limit_method_ = node_chroma->algorithm; - limit_channel_ = node_chroma->channel; - matte_channel_ = custom2; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cc b/source/blender/compositor/operations/COM_ChromaMatteOperation.cc deleted file mode 100644 index 81ce18ac4f3..00000000000 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ChromaMatteOperation.h" - -namespace blender::compositor { - -ChromaMatteOperation::ChromaMatteOperation() -{ - add_input_socket(DataType::Color); - add_input_socket(DataType::Color); - add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -void ChromaMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const float acceptance = settings_->t1; /* In radians. */ - const float cutoff = settings_->t2; /* In radians. */ - const float gain = settings_->fstrength; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *in_image = it.in(0); - const float *in_key = it.in(1); - - /* Store matte(alpha) value in [0] to go with - * #COM_SetAlphaMultiplyOperation and the Value output. */ - - /* Algorithm from book "Video Demystified", does not include the spill reduction part. */ - /* Find theta, the angle that the color space should be rotated based on key. */ - - /* Rescale to `-1.0..1.0`. */ - // const float image_Y = (in_image[0] * 2.0f) - 1.0f; // UNUSED - const float image_cb = (in_image[1] * 2.0f) - 1.0f; - const float image_cr = (in_image[2] * 2.0f) - 1.0f; - - // const float key_Y = (in_key[0] * 2.0f) - 1.0f; // UNUSED - const float key_cb = (in_key[1] * 2.0f) - 1.0f; - const float key_cr = (in_key[2] * 2.0f) - 1.0f; - - const float theta = atan2(key_cr, key_cb); - - /* Rotate the cb and cr into x/z space. */ - const float x_angle = image_cb * cosf(theta) + image_cr * sinf(theta); - const float z_angle = image_cr * cosf(theta) - image_cb * sinf(theta); - - /* If within the acceptance angle. */ - /* If kfg is <0 then the pixel is outside of the key color. */ - const float kfg = x_angle - (fabsf(z_angle) / tanf(acceptance / 2.0f)); - - if (kfg > 0.0f) { /* Found a pixel that is within key color. */ - const float beta = atan2(z_angle, x_angle); - float alpha = 1.0f - (kfg / gain); - - /* Ff beta is within the cutoff angle. */ - if (fabsf(beta) < (cutoff / 2.0f)) { - alpha = 0.0f; - } - - /* Don't make something that was more transparent less transparent. */ - it.out[0] = alpha < in_image[3] ? alpha : in_image[3]; - } - else { /* Pixel is outside key color. */ - it.out[0] = in_image[3]; /* Make pixel just as transparent as it was before. */ - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h deleted file mode 100644 index 72ceb3d9160..00000000000 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ChromaMatteOperation : public MultiThreadedOperation { - private: - NodeChroma *settings_; - - public: - ChromaMatteOperation(); - - void set_settings(NodeChroma *node_chroma) - { - settings_ = node_chroma; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc deleted file mode 100644 index c3911ef10be..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorBalanceASCCDLOperation.h" - -namespace blender::compositor { - -inline float colorbalance_cdl(float in, float offset, float power, float slope) -{ - float x = in * slope + offset; - - /* prevent NaN */ - if (x < 0.0f) { - x = 0.0f; - } - - return powf(x, power); -} - -ColorBalanceASCCDLOperation::ColorBalanceASCCDLOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(1); - flags_.can_be_constant = true; -} - -void ColorBalanceASCCDLOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_factor = p.ins[0]; - const float *in_color = p.ins[1]; - const float fac = std::min(1.0f, in_factor[0]); - const float fac_m = 1.0f - fac; - p.out[0] = fac_m * in_color[0] + - fac * colorbalance_cdl(in_color[0], offset_[0], power_[0], slope_[0]); - p.out[1] = fac_m * in_color[1] + - fac * colorbalance_cdl(in_color[1], offset_[1], power_[1], slope_[1]); - p.out[2] = fac_m * in_color[2] + - fac * colorbalance_cdl(in_color[2], offset_[2], power_[2], slope_[2]); - p.out[3] = in_color[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h deleted file mode 100644 index 75772678802..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ColorBalanceASCCDLOperation : public MultiThreadedRowOperation { - protected: - float offset_[3]; - float power_[3]; - float slope_[3]; - - public: - ColorBalanceASCCDLOperation(); - - void set_offset(float offset[3]) - { - copy_v3_v3(offset_, offset); - } - void set_power(float power[3]) - { - copy_v3_v3(power_, power); - } - void set_slope(float slope[3]) - { - copy_v3_v3(slope_, slope); - } - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc deleted file mode 100644 index 0ebad370beb..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorBalanceLGGOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -inline float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float gain) -{ - /* 1:1 match with the sequencer with linear/srgb conversions, the conversion isn't pretty - * but best keep it this way, since testing for durian shows a similar calculation - * without lin/srgb conversions gives bad results (over-saturated shadows) with colors - * slightly below 1.0. some correction can be done but it ends up looking bad for shadows or - * lighter tones - campbell */ - float x = (((linearrgb_to_srgb(in) - 1.0f) * lift_lgg) + 1.0f) * gain; - - /* prevent NaN */ - if (x < 0.0f) { - x = 0.0f; - } - - return powf(srgb_to_linearrgb(x), gamma_inv); -} - -ColorBalanceLGGOperation::ColorBalanceLGGOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(1); - flags_.can_be_constant = true; -} - -void ColorBalanceLGGOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_factor = p.ins[0]; - const float *in_color = p.ins[1]; - const float fac = std::min(1.0f, in_factor[0]); - const float fac_m = 1.0f - fac; - p.out[0] = fac_m * in_color[0] + - fac * colorbalance_lgg(in_color[0], lift_[0], gamma_inv_[0], gain_[0]); - p.out[1] = fac_m * in_color[1] + - fac * colorbalance_lgg(in_color[1], lift_[1], gamma_inv_[1], gain_[1]); - p.out[2] = fac_m * in_color[2] + - fac * colorbalance_lgg(in_color[2], lift_[2], gamma_inv_[2], gain_[2]); - p.out[3] = in_color[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h deleted file mode 100644 index 9d25bb1d1dc..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ColorBalanceLGGOperation : public MultiThreadedRowOperation { - protected: - float gain_[3]; - float lift_[3]; - float gamma_inv_[3]; - - public: - ColorBalanceLGGOperation(); - - void set_gain(const float gain[3]) - { - copy_v3_v3(gain_, gain); - } - void set_lift(const float lift[3]) - { - copy_v3_v3(lift_, lift); - } - void set_gamma_inv(const float gamma_inv[3]) - { - copy_v3_v3(gamma_inv_, gamma_inv); - } - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.cc deleted file mode 100644 index 8679799b961..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_color.hh" -#include "BLI_math_matrix.h" - -#include "IMB_colormanagement.hh" - -#include "COM_ColorBalanceWhitepointOperation.h" - -namespace blender::compositor { - -ColorBalanceWhitepointOperation::ColorBalanceWhitepointOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(1); - flags_.can_be_constant = true; -} - -void ColorBalanceWhitepointOperation::init_execution() -{ - float3x3 scene_to_xyz = IMB_colormanagement_get_scene_linear_to_xyz(); - float3x3 xyz_to_scene = IMB_colormanagement_get_xyz_to_scene_linear(); - float3 input = blender::math::whitepoint_from_temp_tint(input_temperature_, input_tint_); - float3 output = blender::math::whitepoint_from_temp_tint(output_temperature_, output_tint_); - float3x3 adaption = blender::math::chromatic_adaption_matrix(input, output); - matrix_ = float4x4(xyz_to_scene * adaption * scene_to_xyz); -} - -void ColorBalanceWhitepointOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_factor = p.ins[0]; - const float *in_color = p.ins[1]; - const float fac = std::min(1.0f, in_factor[0]); - mul_v4_m4v4(p.out, matrix_.ptr(), in_color); - interp_v4_v4v4(p.out, in_color, p.out, fac); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.h b/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.h deleted file mode 100644 index 2cd4d227901..00000000000 --- a/source/blender/compositor/operations/COM_ColorBalanceWhitepointOperation.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -class ColorBalanceWhitepointOperation : public MultiThreadedRowOperation { - protected: - float input_temperature_; - float input_tint_; - float output_temperature_; - float output_tint_; - - float4x4 matrix_; - - public: - ColorBalanceWhitepointOperation(); - - virtual void init_execution() override; - - void set_parameters(const float input_temperature, - const float input_tint, - const float output_temperature, - const float output_tint) - { - input_temperature_ = input_temperature; - input_tint_ = input_tint; - output_temperature_ = output_temperature; - output_tint_ = output_tint; - } - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc deleted file mode 100644 index 157ed2b94b2..00000000000 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorCorrectionOperation.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -ColorCorrectionOperation::ColorCorrectionOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - red_channel_enabled_ = true; - green_channel_enabled_ = true; - blue_channel_enabled_ = true; - flags_.can_be_constant = true; -} - -/* Calculate x^y if the function is defined. Otherwise return the given fallback value. */ -BLI_INLINE float color_correct_powf_safe(const float x, const float y, const float fallback_value) -{ - if (x < 0) { - return fallback_value; - } - return powf(x, y); -} - -void ColorCorrectionOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_color = p.ins[0]; - const float *in_mask = p.ins[1]; - - const float level = (in_color[0] + in_color[1] + in_color[2]) / 3.0f; - float level_shadows = 0.0f; - float level_midtones = 0.0f; - float level_highlights = 0.0f; - constexpr float MARGIN = 0.10f; - constexpr float MARGIN_DIV = 0.5f / MARGIN; - if (level < data_->startmidtones - MARGIN) { - level_shadows = 1.0f; - } - else if (level < data_->startmidtones + MARGIN) { - level_midtones = ((level - data_->startmidtones) * MARGIN_DIV) + 0.5f; - level_shadows = 1.0f - level_midtones; - } - else if (level < data_->endmidtones - MARGIN) { - level_midtones = 1.0f; - } - else if (level < data_->endmidtones + MARGIN) { - level_highlights = ((level - data_->endmidtones) * MARGIN_DIV) + 0.5f; - level_midtones = 1.0f - level_highlights; - } - else { - level_highlights = 1.0f; - } - float contrast = data_->master.contrast; - float saturation = data_->master.saturation; - float gamma = data_->master.gamma; - float gain = data_->master.gain; - float lift = data_->master.lift; - contrast *= level_shadows * data_->shadows.contrast + - level_midtones * data_->midtones.contrast + - level_highlights * data_->highlights.contrast; - saturation *= level_shadows * data_->shadows.saturation + - level_midtones * data_->midtones.saturation + - level_highlights * data_->highlights.saturation; - gamma *= level_shadows * data_->shadows.gamma + level_midtones * data_->midtones.gamma + - level_highlights * data_->highlights.gamma; - gain *= level_shadows * data_->shadows.gain + level_midtones * data_->midtones.gain + - level_highlights * data_->highlights.gain; - lift += level_shadows * data_->shadows.lift + level_midtones * data_->midtones.lift + - level_highlights * data_->highlights.lift; - - const float inv_gamma = 1.0f / gamma; - const float luma = IMB_colormanagement_get_luminance(in_color); - - float r = luma + saturation * (in_color[0] - luma); - float g = luma + saturation * (in_color[1] - luma); - float b = luma + saturation * (in_color[2] - luma); - - r = 0.5f + (r - 0.5f) * contrast; - g = 0.5f + (g - 0.5f) * contrast; - b = 0.5f + (b - 0.5f) * contrast; - - /* Check for negative values to avoid nan. */ - r = color_correct_powf_safe(r * gain + lift, inv_gamma, r); - g = color_correct_powf_safe(g * gain + lift, inv_gamma, g); - b = color_correct_powf_safe(b * gain + lift, inv_gamma, b); - - /* Mix with mask. */ - const float value = std::min(1.0f, in_mask[0]); - const float value_ = 1.0f - value; - r = value_ * in_color[0] + value * r; - g = value_ * in_color[1] + value * g; - b = value_ * in_color[2] + value * b; - - p.out[0] = red_channel_enabled_ ? r : in_color[0]; - p.out[1] = green_channel_enabled_ ? g : in_color[1]; - p.out[2] = blue_channel_enabled_ ? b : in_color[2]; - p.out[3] = in_color[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h deleted file mode 100644 index a386f956e19..00000000000 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -class ColorCorrectionOperation : public MultiThreadedRowOperation { - private: - NodeColorCorrection *data_; - - bool red_channel_enabled_; - bool green_channel_enabled_; - bool blue_channel_enabled_; - - public: - ColorCorrectionOperation(); - - void set_data(NodeColorCorrection *data) - { - data_ = data; - } - void set_red_channel_enabled(bool enabled) - { - red_channel_enabled_ = enabled; - } - void set_green_channel_enabled(bool enabled) - { - green_channel_enabled_ = enabled; - } - void set_blue_channel_enabled(bool enabled) - { - blue_channel_enabled_ = enabled; - } - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cc b/source/blender/compositor/operations/COM_ColorCurveOperation.cc deleted file mode 100644 index 420cd8b5346..00000000000 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorCurveOperation.h" - -#include "BKE_colortools.hh" - -namespace blender::compositor { - -ColorCurveOperation::ColorCurveOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - this->set_canvas_input_index(1); -} -void ColorCurveOperation::init_execution() -{ - CurveBaseOperation::init_execution(); - - BKE_curvemapping_premultiply(curve_mapping_, false); -} - -void ColorCurveOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - CurveMapping *cumap = curve_mapping_; - float bwmul[3]; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - /* Local versions of `cumap->black` and `cumap->white`. */ - const float *black = it.in(2); - const float *white = it.in(3); - /* Get a local `bwmul` value, it's not threadsafe using `cumap->bwmul` and others. */ - BKE_curvemapping_set_black_white_ex(black, white, bwmul); - - const float fac = *it.in(0); - const float *image = it.in(1); - if (fac >= 1.0f) { - BKE_curvemapping_evaluate_premulRGBF_ex(cumap, it.out, image, black, bwmul); - } - else if (fac <= 0.0f) { - copy_v3_v3(it.out, image); - } - else { - float col[4]; - BKE_curvemapping_evaluate_premulRGBF_ex(cumap, col, image, black, bwmul); - interp_v3_v3v3(it.out, image, col, fac); - } - it.out[3] = image[3]; - } -} - -/* Constant level curve mapping. */ - -ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - this->set_canvas_input_index(1); -} -void ConstantLevelColorCurveOperation::init_execution() -{ - CurveBaseOperation::init_execution(); - - BKE_curvemapping_premultiply(curve_mapping_, false); - - BKE_curvemapping_set_black_white(curve_mapping_, black_, white_); -} - -void ConstantLevelColorCurveOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - CurveMapping *cumap = curve_mapping_; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float fac = *it.in(0); - const float *image = it.in(1); - if (fac >= 1.0f) { - BKE_curvemapping_evaluate_premulRGBF(cumap, it.out, image); - } - else if (fac <= 0.0f) { - copy_v3_v3(it.out, image); - } - else { - float col[4]; - BKE_curvemapping_evaluate_premulRGBF(cumap, col, image); - interp_v3_v3v3(it.out, image, col, fac); - } - it.out[3] = image[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h deleted file mode 100644 index 072075c6396..00000000000 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_CurveBaseOperation.h" - -namespace blender::compositor { - -class ColorCurveOperation : public CurveBaseOperation { - public: - ColorCurveOperation(); - - void init_execution() override; - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class ConstantLevelColorCurveOperation : public CurveBaseOperation { - private: - float black_[3]; - float white_[3]; - - public: - ConstantLevelColorCurveOperation(); - - void init_execution() override; - - void set_black_level(float black[3]) - { - copy_v3_v3(black_, black); - } - void set_white_level(float white[3]) - { - copy_v3_v3(white_, white); - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorExposureOperation.cc b/source/blender/compositor/operations/COM_ColorExposureOperation.cc deleted file mode 100644 index 4346a89be09..00000000000 --- a/source/blender/compositor/operations/COM_ColorExposureOperation.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2020 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorExposureOperation.h" - -namespace blender::compositor { - -ExposureOperation::ExposureOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void ExposureOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_value = p.ins[0]; - const float *in_exposure = p.ins[1]; - const float exposure = pow(2, in_exposure[0]); - p.out[0] = in_value[0] * exposure; - p.out[1] = in_value[1] * exposure; - p.out[2] = in_value[2] * exposure; - p.out[3] = in_value[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorExposureOperation.h b/source/blender/compositor/operations/COM_ColorExposureOperation.h deleted file mode 100644 index 8f75a238b8c..00000000000 --- a/source/blender/compositor/operations/COM_ColorExposureOperation.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2020 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -class ExposureOperation : public MultiThreadedRowOperation { - public: - ExposureOperation(); - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cc b/source/blender/compositor/operations/COM_ColorMatteOperation.cc deleted file mode 100644 index 7afa92c7c36..00000000000 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorMatteOperation.h" - -namespace blender::compositor { - -ColorMatteOperation::ColorMatteOperation() -{ - add_input_socket(DataType::Color); - add_input_socket(DataType::Color); - add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -void ColorMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const float hue = settings_->t1; - const float sat = settings_->t2; - const float val = settings_->t3; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *in_color = it.in(0); - const float *in_key = it.in(1); - - /* Store matte(alpha) value in [0] to go with - * COM_SetAlphaMultiplyOperation and the Value output. - */ - - float h_wrap; - if ( - /* Do hue last because it needs to wrap, and does some more checks. */ - - /* #sat */ (fabsf(in_color[1] - in_key[1]) < sat) && - /* #val */ (fabsf(in_color[2] - in_key[2]) < val) && - - /* Multiply by 2 because it wraps on both sides of the hue, - * otherwise 0.5 would key all hue's. */ - - /* #hue */ - ((h_wrap = 2.0f * fabsf(in_color[0] - in_key[0])) < hue || (2.0f - h_wrap) < hue)) - { - it.out[0] = 0.0f; /* Make transparent. */ - } - - else { /* Pixel is outside key color. */ - it.out[0] = in_color[3]; /* Make pixel just as transparent as it was before. */ - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h deleted file mode 100644 index 2c02eda0bca..00000000000 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ColorMatteOperation : public MultiThreadedOperation { - private: - NodeChroma *settings_; - - public: - ColorMatteOperation(); - - void set_settings(NodeChroma *node_chroma) - { - settings_ = node_chroma; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.cc b/source/blender/compositor/operations/COM_ColorRampOperation.cc deleted file mode 100644 index bc7342e249f..00000000000 --- a/source/blender/compositor/operations/COM_ColorRampOperation.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorRampOperation.h" - -#include "BKE_colorband.hh" - -namespace blender::compositor { - -ColorRampOperation::ColorRampOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - - color_band_ = nullptr; - flags_.can_be_constant = true; -} - -void ColorRampOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - BKE_colorband_evaluate(color_band_, *it.in(0), it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h deleted file mode 100644 index 8d16d5419d7..00000000000 --- a/source/blender/compositor/operations/COM_ColorRampOperation.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_texture_types.h" - -namespace blender::compositor { - -class ColorRampOperation : public MultiThreadedOperation { - private: - ColorBand *color_band_; - - public: - ColorRampOperation(); - - void set_color_band(ColorBand *color_band) - { - color_band_ = color_band; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cc b/source/blender/compositor/operations/COM_ColorSpillOperation.cc deleted file mode 100644 index a206ed2f637..00000000000 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ColorSpillOperation.h" -#define AVG(a, b) ((a + b) / 2) - -namespace blender::compositor { - -ColorSpillOperation::ColorSpillOperation() -{ - add_input_socket(DataType::Color); - add_input_socket(DataType::Value); - add_output_socket(DataType::Color); - - spill_channel_ = 1; /* GREEN */ - spill_method_ = 0; - flags_.can_be_constant = true; -} - -void ColorSpillOperation::init_execution() -{ - if (spill_channel_ == 0) { - rmut_ = -1.0f; - gmut_ = 1.0f; - bmut_ = 1.0f; - channel2_ = 1; - channel3_ = 2; - if (settings_->unspill == 0) { - settings_->uspillr = 1.0f; - settings_->uspillg = 0.0f; - settings_->uspillb = 0.0f; - } - } - else if (spill_channel_ == 1) { - rmut_ = 1.0f; - gmut_ = -1.0f; - bmut_ = 1.0f; - channel2_ = 0; - channel3_ = 2; - if (settings_->unspill == 0) { - settings_->uspillr = 0.0f; - settings_->uspillg = 1.0f; - settings_->uspillb = 0.0f; - } - } - else { - rmut_ = 1.0f; - gmut_ = 1.0f; - bmut_ = -1.0f; - - channel2_ = 0; - channel3_ = 1; - if (settings_->unspill == 0) { - settings_->uspillr = 0.0f; - settings_->uspillg = 0.0f; - settings_->uspillb = 1.0f; - } - } -} - -void ColorSpillOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - const float factor = std::min(1.0f, *it.in(1)); - - float map; - switch (spill_method_) { - case 0: /* simple */ - map = factor * (color[spill_channel_] - (settings_->limscale * color[settings_->limchan])); - break; - default: /* average */ - map = factor * (color[spill_channel_] - - (settings_->limscale * AVG(color[channel2_], color[channel3_]))); - break; - } - - if (map > 0.0f) { - it.out[0] = color[0] + rmut_ * (settings_->uspillr * map); - it.out[1] = color[1] + gmut_ * (settings_->uspillg * map); - it.out[2] = color[2] + bmut_ * (settings_->uspillb * map); - it.out[3] = color[3]; - } - else { - copy_v4_v4(it.out, color); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h deleted file mode 100644 index 2c18104e567..00000000000 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ColorSpillOperation : public MultiThreadedOperation { - protected: - NodeColorspill *settings_; - int spill_channel_; - int spill_method_; - int channel2_; - int channel3_; - float rmut_, gmut_, bmut_; - - public: - ColorSpillOperation(); - - void init_execution() override; - - void set_settings(NodeColorspill *node_color_spill) - { - settings_ = node_color_spill; - } - void set_spill_channel(int channel) - { - spill_channel_ = channel; - } - void set_spill_method(int method) - { - spill_method_ = method; - } - - float calculate_map_value(float fac, float *input); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cc b/source/blender/compositor/operations/COM_CompositorOperation.cc deleted file mode 100644 index 21d3ccac388..00000000000 --- a/source/blender/compositor/operations/COM_CompositorOperation.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CompositorOperation.h" - -#include "BLI_string.h" - -#include "BKE_global.hh" -#include "BKE_image.hh" -#include "BKE_scene.hh" - -#include "IMB_imbuf.hh" - -#include "RE_pipeline.h" - -namespace blender::compositor { - -CompositorOperation::CompositorOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - - this->set_render_data(nullptr); - output_buffer_ = nullptr; - - use_alpha_input_ = false; - active_ = false; - - scene_ = nullptr; - scene_name_[0] = '\0'; - view_name_ = nullptr; - - flags_.use_render_border = true; -} - -void CompositorOperation::init_execution() -{ - if (!active_) { - return; - } - - /* When initializing the tree during initial load the width and height can be zero. */ - if (this->get_width() * this->get_height() != 0) { - output_buffer_ = (float *)MEM_callocN( - sizeof(float[4]) * this->get_width() * this->get_height(), "CompositorOperation"); - } -} - -void CompositorOperation::deinit_execution() -{ - if (!active_) { - return; - } - - if (!is_braked()) { - Render *re = RE_GetSceneRender(scene_); - RenderResult *rr = RE_AcquireResultWrite(re); - - if (rr) { - RenderView *rv = RE_RenderViewGetByName(rr, view_name_); - ImBuf *ibuf = RE_RenderViewEnsureImBuf(rr, rv); - - IMB_assign_float_buffer(ibuf, output_buffer_, IB_TAKE_OWNERSHIP); - - rr->have_combined = true; - } - else { - if (output_buffer_) { - MEM_freeN(output_buffer_); - } - } - - if (re) { - RE_ReleaseResult(re); - re = nullptr; - } - - Image *image = BKE_image_ensure_viewer(G.main, IMA_TYPE_R_RESULT, "Render Result"); - BKE_image_partial_update_mark_full_update(image); - BLI_thread_lock(LOCK_DRAW_IMAGE); - BKE_image_signal(G.main, image, nullptr, IMA_SIGNAL_FREE); - BLI_thread_unlock(LOCK_DRAW_IMAGE); - } - else { - if (output_buffer_) { - MEM_freeN(output_buffer_); - } - } - - output_buffer_ = nullptr; -} - -void CompositorOperation::set_scene_name(const char *scene_name) -{ - STRNCPY(scene_name_, scene_name); -} - -void CompositorOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, - const rcti &area, - Span inputs) -{ - if (!output_buffer_) { - return; - } - MemoryBuffer output_buf(output_buffer_, COM_DATA_TYPE_COLOR_CHANNELS, get_width(), get_height()); - output_buf.copy_from(inputs[0], area); - if (use_alpha_input_) { - output_buf.copy_from(inputs[1], area, 0, COM_DATA_TYPE_VALUE_CHANNELS, 3); - } -} - -void CompositorOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - int width, height; - BKE_render_resolution(rd_, false, &width, &height); - - /* Check actual render resolution with cropping it may differ with cropped border.rendering - * Fix for #31777 Border Crop gives black (easy). */ - Render *re = RE_GetSceneRender(scene_); - if (re) { - RenderResult *rr = RE_AcquireResultRead(re); - if (rr) { - width = rr->rectx; - height = rr->recty; - } - RE_ReleaseResult(re); - } - - rcti local_preferred; - BLI_rcti_init(&local_preferred, 0, width, 0, height); - - set_determined_canvas_modifier([&](rcti &canvas) { canvas = local_preferred; }); - NodeOperation::determine_canvas(local_preferred, r_area); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h deleted file mode 100644 index a0eebe9c471..00000000000 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -struct Scene; - -namespace blender::compositor { - -/** - * \brief Compositor output operation - */ -class CompositorOperation : public MultiThreadedOperation { - private: - const struct Scene *scene_; - /** - * \brief Scene name, used for getting the render output, includes 'SC' prefix. - */ - char scene_name_[MAX_ID_NAME]; - - /** - * \brief local reference to the scene - */ - const RenderData *rd_; - - /** - * \brief reference to the output float buffer - */ - float *output_buffer_; - - /** - * \brief Ignore any alpha input - */ - bool use_alpha_input_; - - /** - * \brief operation is active for calculating final compo result - */ - bool active_; - - /** - * \brief View name, used for multiview - */ - const char *view_name_; - - public: - CompositorOperation(); - bool is_active_compositor_output() const - { - return active_; - } - void set_scene(const struct Scene *scene) - { - scene_ = scene; - } - void set_scene_name(const char *scene_name); - void set_view_name(const char *view_name) - { - view_name_ = view_name; - } - void set_render_data(const RenderData *rd) - { - rd_ = rd; - } - bool is_output_operation(bool /*rendering*/) const override - { - return this->is_active_compositor_output(); - } - void init_execution() override; - void deinit_execution() override; - eCompositorPriority get_render_priority() const override - { - return eCompositorPriority::Medium; - } - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - void set_use_alpha_input(bool value) - { - use_alpha_input_ = value; - } - void set_active(bool active) - { - active_ = active; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc deleted file mode 100644 index 527a9b2a449..00000000000 --- a/source/blender/compositor/operations/COM_ConstantOperation.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -ConstantOperation::ConstantOperation() -{ - needs_canvas_to_get_constant_ = false; - flags_.is_constant_operation = true; -} - -bool ConstantOperation::can_get_constant_elem() const -{ - return !needs_canvas_to_get_constant_ || flags_.is_canvas_set; -} - -void ConstantOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - BLI_assert(output->is_a_single_elem()); - const float *constant = get_constant_elem(); - float *out = output->get_elem(area.xmin, area.ymin); - memcpy(out, constant, output->get_elem_bytes_len()); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConstantOperation.h b/source/blender/compositor/operations/COM_ConstantOperation.h deleted file mode 100644 index 94b97e3d177..00000000000 --- a/source/blender/compositor/operations/COM_ConstantOperation.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -/* TODO(manzanilla): After removing tiled implementation, implement a default #determine_resolution - * for all constant operations and make all initialization and de-initialization methods final. */ -/** - * Base class for operations that are always constant. Operations that can be constant only when - * all their inputs are so, are evaluated into primitive constants (Color/Vector/Value) during - * constant folding. - */ -class ConstantOperation : public NodeOperation { - protected: - bool needs_canvas_to_get_constant_; - - public: - ConstantOperation(); - - /** May require resolution to be already determined. */ - virtual const float *get_constant_elem() = 0; - bool can_get_constant_elem() const; - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cc b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cc deleted file mode 100644 index 95464a14940..00000000000 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cc +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvertColorProfileOperation.h" - -#include "IMB_imbuf.hh" - -namespace blender::compositor { - -ConvertColorProfileOperation::ConvertColorProfileOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - predivided_ = false; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h deleted file mode 100644 index 09cf3e528de..00000000000 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ConvertColorProfileOperation : public NodeOperation { - private: - /** - * \brief color profile where to convert from - */ - int from_profile_; - - /** - * \brief color profile where to convert to - */ - int to_profile_; - - /** - * \brief is color predivided - */ - bool predivided_; - - public: - /** - * Default constructor - */ - ConvertColorProfileOperation(); - - void set_from_color_profile(int color_profile) - { - from_profile_ = color_profile; - } - void set_to_color_profile(int color_profile) - { - to_profile_ = color_profile; - } - void set_predivided(bool predivided) - { - predivided_ = predivided; - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc deleted file mode 100644 index 89af6187112..00000000000 --- a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvertColorSpaceOperation.h" - -#include "BLI_string.h" - -namespace blender::compositor { - -ConvertColorSpaceOperation::ConvertColorSpaceOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - color_processor_ = nullptr; -} - -void ConvertColorSpaceOperation::set_settings(NodeConvertColorSpace *node_color_space) -{ - this->settings_ = node_color_space; -} - -void ConvertColorSpaceOperation::init_execution() -{ - if (BLI_strnlen(settings_->from_color_space, sizeof(settings_->from_color_space)) == 0 || - BLI_strnlen(settings_->to_color_space, sizeof(settings_->to_color_space)) == 0) - { - return; - } - - int in_colorspace_index = IMB_colormanagement_colorspace_get_named_index( - settings_->from_color_space); - int out_colorspace_index = IMB_colormanagement_colorspace_get_named_index( - settings_->to_color_space); - - if (in_colorspace_index == 0 || out_colorspace_index == 0) { - return; - } - - color_processor_ = IMB_colormanagement_colorspace_processor_new(settings_->from_color_space, - settings_->to_color_space); -} - -void ConvertColorSpaceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - copy_v4_v4(it.out, it.in(0)); - } - - if (color_processor_ != nullptr) { - output->apply_processor(*color_processor_, area); - } -} - -void ConvertColorSpaceOperation::deinit_execution() -{ - if (color_processor_ != nullptr) { - IMB_colormanagement_processor_free(color_processor_); - } - this->color_processor_ = nullptr; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h b/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h deleted file mode 100644 index d60d0336dfb..00000000000 --- a/source/blender/compositor/operations/COM_ConvertColorSpaceOperation.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConvertColorSpaceNode.h" -#include "COM_MultiThreadedOperation.h" -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -class ConvertColorSpaceOperation : public MultiThreadedOperation { - private: - NodeConvertColorSpace *settings_; - ColormanageProcessor *color_processor_; - - public: - ConvertColorSpaceOperation(); - - void set_settings(NodeConvertColorSpace *node_color_space); - - void init_execution() override; - void deinit_execution() override; - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc deleted file mode 100644 index 4ecf27c4a09..00000000000 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_base.hh" - -#include "DNA_camera_types.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "BKE_camera.h" - -#include "COM_ConvertDepthToRadiusOperation.h" - -namespace blender::compositor { - -ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); - flags_.can_be_constant = true; -} - -void ConvertDepthToRadiusOperation::init_execution() -{ - depth_input_operation_ = this->get_input_socket_reader(0); - image_input_operation_ = this->get_input_socket_reader(1); - - f_stop = get_f_stop(); - focal_length = get_focal_length(); - max_radius = data_->maxblur; - pixels_per_meter = compute_pixels_per_meter(); - distance_to_image_of_focus = compute_distance_to_image_of_focus(); - - NodeBlurData blur_data; - blur_data.sizex = compute_maximum_defocus_radius(); - blur_data.sizey = blur_data.sizex; - blur_data.relative = false; - blur_data.filtertype = R_FILTER_GAUSS; - - blur_x_operation_->set_data(&blur_data); - blur_x_operation_->set_size(1.0f); - blur_y_operation_->set_data(&blur_data); - blur_y_operation_->set_size(1.0f); -} - -/* Given a depth texture, compute the radius of the circle of confusion in pixels based on equation - * (8) of the paper: - * - * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic - * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305. */ -void ConvertDepthToRadiusOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float depth = *it.in(0); - - /* Compute `Vu` in equation (7). */ - const float distance_to_image_of_object = (focal_length * depth) / (depth - focal_length); - - /* Compute C in equation (8). Notice that the last multiplier was included in the absolute - * since it is negative when the object distance is less than the focal length, as noted in - * equation (7). */ - float diameter = abs((distance_to_image_of_object - distance_to_image_of_focus) * - (focal_length / (f_stop * distance_to_image_of_object))); - - /* The diameter is in meters, so multiply by the pixels per meter. */ - float radius = (diameter / 2.0f) * pixels_per_meter; - - *it.out = math::min(max_radius, radius); - } -} - -/* Computes the maximum possible defocus radius in pixels. */ -float ConvertDepthToRadiusOperation::compute_maximum_defocus_radius() const -{ - const float maximum_diameter = compute_maximum_diameter_of_circle_of_confusion(); - const float pixels_per_meter = compute_pixels_per_meter(); - const float radius = (maximum_diameter / 2.0f) * pixels_per_meter; - return math::min(radius, data_->maxblur); -} - -/* Computes the diameter of the circle of confusion at infinity. This computes the limit in - * figure (5) of the paper: - * - * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic - * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305. - * - * Notice that the diameter is asymmetric around the focus point, and we are computing the - * limiting diameter at infinity, while another limiting diameter exist at zero distance from the - * lens. This is a limitation of the implementation, as it assumes far defocusing only. */ -float ConvertDepthToRadiusOperation::compute_maximum_diameter_of_circle_of_confusion() const -{ - const float f_stop = get_f_stop(); - const float focal_length = get_focal_length(); - const float distance_to_image_of_focus = compute_distance_to_image_of_focus(); - return math::abs((distance_to_image_of_focus / (f_stop * focal_length)) - - (focal_length / f_stop)); -} - -/* Computes the distance in meters to the image of the focus point across a lens of the specified - * focal length. This computes `Vp` in equation (7) of the paper: - * - * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic - * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305. */ -float ConvertDepthToRadiusOperation::compute_distance_to_image_of_focus() const -{ - const float focal_length = get_focal_length(); - const float focus_distance = compute_focus_distance(); - return (focal_length * focus_distance) / (focus_distance - focal_length); -} - -/* Returns the focal length in meters. Fallback to 50 mm in case of an invalid camera. Ensure a - * minimum of 1e-6. */ -float ConvertDepthToRadiusOperation::get_focal_length() const -{ - const Camera *camera = get_camera(); - return camera ? math::max(1e-6f, camera->lens / 1000.0f) : 50.0f / 1000.0f; -} - -/* Computes the distance to the point that is completely in focus. Default to 10 meters for null - * camera. */ -float ConvertDepthToRadiusOperation::compute_focus_distance() const -{ - const Object *camera_object = get_camera_object(); - if (!camera_object) { - return 10.0f; - } - return BKE_camera_object_dof_distance(camera_object); -} - -/* Computes the number of pixels per meter of the sensor size. This is essentially the resolution - * over the sensor size, using the sensor fit axis. Fallback to DEFAULT_SENSOR_WIDTH in case of - * an invalid camera. Note that the stored sensor size is in millimeter, so convert to meters. */ -float ConvertDepthToRadiusOperation::compute_pixels_per_meter() const -{ - const int2 size = int2(image_input_operation_->get_width(), - image_input_operation_->get_height()); - const Camera *camera = get_camera(); - const float default_value = size.x / (DEFAULT_SENSOR_WIDTH / 1000.0f); - if (!camera) { - return default_value; - } - - switch (camera->sensor_fit) { - case CAMERA_SENSOR_FIT_HOR: - return size.x / (camera->sensor_x / 1000.0f); - case CAMERA_SENSOR_FIT_VERT: - return size.y / (camera->sensor_y / 1000.0f); - case CAMERA_SENSOR_FIT_AUTO: { - return size.x > size.y ? size.x / (camera->sensor_x / 1000.0f) : - size.y / (camera->sensor_y / 1000.0f); - } - default: - break; - } - - return default_value; -} - -/* Returns the f-stop number. Fallback to 1e-3 for zero f-stop. */ -float ConvertDepthToRadiusOperation::get_f_stop() const -{ - return math::max(1e-3f, data_->fstop); -} - -const Camera *ConvertDepthToRadiusOperation::get_camera() const -{ - const Object *camera_object = get_camera_object(); - if (!camera_object || camera_object->type != OB_CAMERA) { - return nullptr; - } - - return reinterpret_cast(camera_object->data); -} - -const Object *ConvertDepthToRadiusOperation::get_camera_object() const -{ - return scene_->camera; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h deleted file mode 100644 index e8ef8592999..00000000000 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GaussianBlurBaseOperation.h" -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class ConvertDepthToRadiusOperation : public MultiThreadedOperation { - private: - SocketReader *depth_input_operation_; - SocketReader *image_input_operation_; - - const Scene *scene_; - const NodeDefocus *data_; - - float f_stop; - float max_radius; - float focal_length; - float pixels_per_meter; - float distance_to_image_of_focus; - - GaussianXBlurOperation *blur_x_operation_; - GaussianYBlurOperation *blur_y_operation_; - - public: - ConvertDepthToRadiusOperation(); - - void init_execution() override; - - void set_data(const NodeDefocus *data) - { - data_ = data; - } - - void set_scene(const Scene *scene) - { - scene_ = scene; - } - - void set_blur_x_operation(GaussianXBlurOperation *blur_x_operation) - { - blur_x_operation_ = blur_x_operation; - } - - void set_blur_y_operation(GaussianYBlurOperation *blur_y_operation) - { - blur_y_operation_ = blur_y_operation; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - float compute_maximum_defocus_radius() const; - float compute_maximum_diameter_of_circle_of_confusion() const; - float compute_distance_to_image_of_focus() const; - float get_focal_length() const; - float compute_focus_distance() const; - float compute_pixels_per_meter() const; - float get_f_stop() const; - const Camera *get_camera() const; - const Object *get_camera_object() const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cc b/source/blender/compositor/operations/COM_ConvertOperation.cc deleted file mode 100644 index b51ad2a1e35..00000000000 --- a/source/blender/compositor/operations/COM_ConvertOperation.cc +++ /dev/null @@ -1,411 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvertOperation.h" - -#include "BLI_color.hh" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -ConvertBaseOperation::ConvertBaseOperation() -{ - flags_.can_be_constant = true; -} - -void ConvertBaseOperation::hash_output_params() {} - -void ConvertBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - BuffersIterator it = output->iterate_with(inputs, area); - update_memory_buffer_partial(it); -} - -std::unique_ptr ConvertBaseOperation::get_meta_data() -{ - if (this->get_input_operation(0)) { - this->get_input_operation(0)->get_meta_data(); - } - - return nullptr; -} - -/* ******** Value to Color ******** */ - -ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); -} - -void ConvertValueToColorOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - it.out[0] = it.out[1] = it.out[2] = *it.in(0); - it.out[3] = 1.0f; - } -} - -/* ******** Color to Value ******** */ - -ConvertColorToValueOperation::ConvertColorToValueOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); -} - -void ConvertColorToValueOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - it.out[0] = (in[0] + in[1] + in[2]) / 3.0f; - } -} - -/* ******** Color to BW ******** */ - -ConvertColorToBWOperation::ConvertColorToBWOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); -} - -void ConvertColorToBWOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - it.out[0] = IMB_colormanagement_get_luminance(it.in(0)); - } -} - -/* ******** Color to Vector ******** */ - -ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Vector); -} - -void ConvertColorToVectorOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - copy_v3_v3(it.out, it.in(0)); - } -} - -/* ******** Value to Vector ******** */ - -ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Vector); -} - -void ConvertValueToVectorOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - it.out[0] = it.out[1] = it.out[2] = *it.in(0); - } -} - -/* ******** Vector to Color ******** */ - -ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Vector); - this->add_output_socket(DataType::Color); -} - -void ConvertVectorToColorOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - copy_v3_v3(it.out, it.in(0)); - it.out[3] = 1.0f; - } -} - -/* ******** Vector to Value ******** */ - -ConvertVectorToValueOperation::ConvertVectorToValueOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Vector); - this->add_output_socket(DataType::Value); -} - -void ConvertVectorToValueOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - it.out[0] = (in[0] + in[1] + in[2]) / 3.0f; - } -} - -/* ******** RGB to YCC ******** */ - -ConvertRGBToYCCOperation::ConvertRGBToYCCOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertRGBToYCCOperation::set_mode(int mode) -{ - switch (mode) { - case 0: - mode_ = BLI_YCC_ITU_BT601; - break; - case 2: - mode_ = BLI_YCC_JFIF_0_255; - break; - case 1: - default: - mode_ = BLI_YCC_ITU_BT709; - break; - } -} - -void ConvertRGBToYCCOperation::hash_output_params() -{ - ConvertBaseOperation::hash_output_params(); - hash_param(mode_); -} - -void ConvertRGBToYCCOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - rgb_to_ycc(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], mode_); - - /* Normalize for viewing (#rgb_to_ycc returns 0-255 values). */ - mul_v3_fl(it.out, 1.0f / 255.0f); - it.out[3] = in[3]; - } -} - -/* ******** YCC to RGB ******** */ - -ConvertYCCToRGBOperation::ConvertYCCToRGBOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertYCCToRGBOperation::set_mode(int mode) -{ - switch (mode) { - case 0: - mode_ = BLI_YCC_ITU_BT601; - break; - case 2: - mode_ = BLI_YCC_JFIF_0_255; - break; - case 1: - default: - mode_ = BLI_YCC_ITU_BT709; - break; - } -} - -void ConvertYCCToRGBOperation::hash_output_params() -{ - ConvertBaseOperation::hash_output_params(); - hash_param(mode_); -} - -void ConvertYCCToRGBOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - /* Multiply by 255 to un-normalize (#ycc_to_rgb needs input values in 0-255 range). */ - ycc_to_rgb( - in[0] * 255.0f, in[1] * 255.0f, in[2] * 255.0f, &it.out[0], &it.out[1], &it.out[2], mode_); - it.out[3] = in[3]; - } -} - -/* ******** RGB to YUV ******** */ - -ConvertRGBToYUVOperation::ConvertRGBToYUVOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertRGBToYUVOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - rgb_to_yuv(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], BLI_YUV_ITU_BT709); - it.out[3] = in[3]; - } -} - -/* ******** YUV to RGB ******** */ - -ConvertYUVToRGBOperation::ConvertYUVToRGBOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertYUVToRGBOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - yuv_to_rgb(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], BLI_YUV_ITU_BT709); - it.out[3] = in[3]; - } -} - -/* ******** RGB to HSV ******** */ - -ConvertRGBToHSVOperation::ConvertRGBToHSVOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertRGBToHSVOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - rgb_to_hsv_v(in, it.out); - it.out[3] = in[3]; - } -} - -/* ******** HSV to RGB ******** */ - -ConvertHSVToRGBOperation::ConvertHSVToRGBOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertHSVToRGBOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - hsv_to_rgb_v(in, it.out); - it.out[0] = max_ff(it.out[0], 0.0f); - it.out[1] = max_ff(it.out[1], 0.0f); - it.out[2] = max_ff(it.out[2], 0.0f); - it.out[3] = in[3]; - } -} - -/* ******** RGB to HSL ******** */ - -ConvertRGBToHSLOperation::ConvertRGBToHSLOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertRGBToHSLOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - rgb_to_hsl_v(in, it.out); - it.out[3] = in[3]; - } -} - -/* ******** HSL to RGB ******** */ - -ConvertHSLToRGBOperation::ConvertHSLToRGBOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertHSLToRGBOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float *in = it.in(0); - hsl_to_rgb_v(in, it.out); - it.out[0] = max_ff(it.out[0], 0.0f); - it.out[1] = max_ff(it.out[1], 0.0f); - it.out[2] = max_ff(it.out[2], 0.0f); - it.out[3] = in[3]; - } -} - -/* ******** Pre-multiplied to Straight ******** */ - -ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertPremulToStraightOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - copy_v4_v4(it.out, ColorSceneLinear4f(it.in(0)).unpremultiply_alpha()); - } -} - -/* ******** Straight to Pre-multiplied ******** */ - -ConvertStraightToPremulOperation::ConvertStraightToPremulOperation() : ConvertBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ConvertStraightToPremulOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - copy_v4_v4(it.out, ColorSceneLinear4f(it.in(0)).premultiply_alpha()); - } -} - -/* ******** Separate Channels ******** */ - -SeparateChannelOperation::SeparateChannelOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); - flags_.can_be_constant = true; -} - -void SeparateChannelOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - it.out[0] = it.in(0)[channel_]; - } -} - -/* ******** Combine Channels ******** */ - -CombineChannelsOperation::CombineChannelsOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - - flags_.can_be_constant = true; -} - -void CombineChannelsOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - it.out[0] = *it.in(0); - it.out[1] = *it.in(1); - it.out[2] = *it.in(2); - it.out[3] = *it.in(3); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h deleted file mode 100644 index ec9ed6f33e2..00000000000 --- a/source/blender/compositor/operations/COM_ConvertOperation.h +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class ConvertBaseOperation : public MultiThreadedOperation { - public: - ConvertBaseOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) final; - - protected: - virtual void hash_output_params() override; - virtual void update_memory_buffer_partial(BuffersIterator &it) = 0; - - /* Returns the meta data of the input if it exists. */ - std::unique_ptr get_meta_data() override; -}; - -class ConvertValueToColorOperation : public ConvertBaseOperation { - public: - ConvertValueToColorOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertColorToValueOperation : public ConvertBaseOperation { - public: - ConvertColorToValueOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertColorToBWOperation : public ConvertBaseOperation { - public: - ConvertColorToBWOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertColorToVectorOperation : public ConvertBaseOperation { - public: - ConvertColorToVectorOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertValueToVectorOperation : public ConvertBaseOperation { - public: - ConvertValueToVectorOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertVectorToColorOperation : public ConvertBaseOperation { - public: - ConvertVectorToColorOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertVectorToValueOperation : public ConvertBaseOperation { - public: - ConvertVectorToValueOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertRGBToYCCOperation : public ConvertBaseOperation { - private: - /** YCbCr mode (JPEG, ITU601, ITU709) */ - int mode_; - - public: - ConvertRGBToYCCOperation(); - - /** Set the YCC mode */ - void set_mode(int mode); - - protected: - void hash_output_params() override; - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertYCCToRGBOperation : public ConvertBaseOperation { - private: - /** YCbCr mode (JPEG, ITU601, ITU709) */ - int mode_; - - public: - ConvertYCCToRGBOperation(); - - /** Set the YCC mode */ - void set_mode(int mode); - - protected: - void hash_output_params() override; - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertRGBToYUVOperation : public ConvertBaseOperation { - public: - ConvertRGBToYUVOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertYUVToRGBOperation : public ConvertBaseOperation { - public: - ConvertYUVToRGBOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertRGBToHSVOperation : public ConvertBaseOperation { - public: - ConvertRGBToHSVOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertHSVToRGBOperation : public ConvertBaseOperation { - public: - ConvertHSVToRGBOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertRGBToHSLOperation : public ConvertBaseOperation { - public: - ConvertRGBToHSLOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertHSLToRGBOperation : public ConvertBaseOperation { - public: - ConvertHSLToRGBOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertPremulToStraightOperation : public ConvertBaseOperation { - public: - ConvertPremulToStraightOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class ConvertStraightToPremulOperation : public ConvertBaseOperation { - public: - ConvertStraightToPremulOperation(); - - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class SeparateChannelOperation : public MultiThreadedOperation { - private: - int channel_; - - public: - SeparateChannelOperation(); - - void set_channel(int channel) - { - channel_ = channel; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class CombineChannelsOperation : public MultiThreadedOperation { - public: - CombineChannelsOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cc b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cc deleted file mode 100644 index e4d0d967de7..00000000000 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvolutionEdgeFilterOperation.h" - -namespace blender::compositor { - -void ConvolutionEdgeFilterOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX]; - const int last_x = get_width() - 1; - const int last_y = get_height() - 1; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int left_offset = (it.x == 0) ? 0 : -image->elem_stride; - const int right_offset = (it.x == last_x) ? 0 : image->elem_stride; - const int down_offset = (it.y == 0) ? 0 : -image->row_stride; - const int up_offset = (it.y == last_y) ? 0 : image->row_stride; - - const float *center_color = it.in(IMAGE_INPUT_INDEX); - float res1[4] = {0}; - float res2[4] = {0}; - - const float *color = center_color + down_offset + left_offset; - madd_v3_v3fl(res1, color, filter_[0]); - copy_v3_v3(res2, res1); - - color = center_color + down_offset; - madd_v3_v3fl(res1, color, filter_[1]); - madd_v3_v3fl(res2, color, filter_[3]); - - color = center_color + down_offset + right_offset; - madd_v3_v3fl(res1, color, filter_[2]); - madd_v3_v3fl(res2, color, filter_[6]); - - color = center_color + left_offset; - madd_v3_v3fl(res1, color, filter_[3]); - madd_v3_v3fl(res2, color, filter_[1]); - - { - float rgb_filtered[3]; - mul_v3_v3fl(rgb_filtered, center_color, filter_[4]); - add_v3_v3(res1, rgb_filtered); - add_v3_v3(res2, rgb_filtered); - } - - color = center_color + right_offset; - madd_v3_v3fl(res1, color, filter_[5]); - madd_v3_v3fl(res2, color, filter_[7]); - - color = center_color + up_offset + left_offset; - madd_v3_v3fl(res1, color, filter_[6]); - madd_v3_v3fl(res2, color, filter_[2]); - - color = center_color + up_offset; - madd_v3_v3fl(res1, color, filter_[7]); - madd_v3_v3fl(res2, color, filter_[5]); - - { - color = center_color + up_offset + right_offset; - float rgb_filtered[3]; - mul_v3_v3fl(rgb_filtered, color, filter_[8]); - add_v3_v3(res1, rgb_filtered); - add_v3_v3(res2, rgb_filtered); - } - - it.out[0] = sqrt(res1[0] * res1[0] + res2[0] * res2[0]); - it.out[1] = sqrt(res1[1] * res1[1] + res2[1] * res2[1]); - it.out[2] = sqrt(res1[2] * res1[2] + res2[2] * res2[2]); - - const float factor = *it.in(FACTOR_INPUT_INDEX); - const float factor_ = 1.0f - factor; - it.out[0] = it.out[0] * factor + center_color[0] * factor_; - it.out[1] = it.out[1] * factor + center_color[1] * factor_; - it.out[2] = it.out[2] * factor + center_color[2] * factor_; - - it.out[3] = center_color[3]; - - /* Make sure we don't return negative color. */ - CLAMP4_MIN(it.out, 0.0f); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h deleted file mode 100644 index 9411a221d4a..00000000000 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConvolutionFilterOperation.h" - -namespace blender::compositor { - -class ConvolutionEdgeFilterOperation : public ConvolutionFilterOperation { - public: - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cc b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cc deleted file mode 100644 index 14b5df26e6f..00000000000 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ConvolutionFilterOperation.h" - -namespace blender::compositor { - -ConvolutionFilterOperation::ConvolutionFilterOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - flags_.can_be_constant = true; -} - -void ConvolutionFilterOperation::set3x3Filter( - float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9) -{ - filter_[0] = f1; - filter_[1] = f2; - filter_[2] = f3; - filter_[3] = f4; - filter_[4] = f5; - filter_[5] = f6; - filter_[6] = f7; - filter_[7] = f8; - filter_[8] = f9; - filter_height_ = 3; - filter_width_ = 3; -} - -void ConvolutionFilterOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: { - const int add_x = (filter_width_ - 1) / 2 + 1; - const int add_y = (filter_height_ - 1) / 2 + 1; - r_input_area.xmin = output_area.xmin - add_x; - r_input_area.xmax = output_area.xmax + add_x; - r_input_area.ymin = output_area.ymin - add_y; - r_input_area.ymax = output_area.ymax + add_y; - break; - } - case FACTOR_INPUT_INDEX: { - r_input_area = output_area; - break; - } - } -} - -void ConvolutionFilterOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX]; - const int last_x = get_width() - 1; - const int last_y = get_height() - 1; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int left_offset = (it.x == 0) ? 0 : -image->elem_stride; - const int right_offset = (it.x == last_x) ? 0 : image->elem_stride; - const int down_offset = (it.y == 0) ? 0 : -image->row_stride; - const int up_offset = (it.y == last_y) ? 0 : image->row_stride; - - const float *center_color = it.in(IMAGE_INPUT_INDEX); - zero_v4(it.out); - madd_v4_v4fl(it.out, center_color + down_offset + left_offset, filter_[0]); - madd_v4_v4fl(it.out, center_color + down_offset, filter_[1]); - madd_v4_v4fl(it.out, center_color + down_offset + right_offset, filter_[2]); - madd_v4_v4fl(it.out, center_color + left_offset, filter_[3]); - madd_v4_v4fl(it.out, center_color, filter_[4]); - madd_v4_v4fl(it.out, center_color + right_offset, filter_[5]); - madd_v4_v4fl(it.out, center_color + up_offset + left_offset, filter_[6]); - madd_v4_v4fl(it.out, center_color + up_offset, filter_[7]); - madd_v4_v4fl(it.out, center_color + up_offset + right_offset, filter_[8]); - - const float factor = *it.in(FACTOR_INPUT_INDEX); - const float factor_ = 1.0f - factor; - it.out[0] = it.out[0] * factor + center_color[0] * factor_; - it.out[1] = it.out[1] * factor + center_color[1] * factor_; - it.out[2] = it.out[2] * factor + center_color[2] * factor_; - it.out[3] = it.out[3] * factor + center_color[3] * factor_; - - /* Make sure we don't return negative color. */ - CLAMP4_MIN(it.out, 0.0f); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h deleted file mode 100644 index 2ed01dea786..00000000000 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class ConvolutionFilterOperation : public MultiThreadedOperation { - protected: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int FACTOR_INPUT_INDEX = 1; - - private: - int filter_width_; - int filter_height_; - - protected: - float filter_[9]; - - public: - ConvolutionFilterOperation(); - void set3x3Filter( - float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9); - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final; - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CropOperation.cc b/source/blender/compositor/operations/COM_CropOperation.cc deleted file mode 100644 index ce5d1c93159..00000000000 --- a/source/blender/compositor/operations/COM_CropOperation.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_vector_types.hh" - -#include "COM_CropOperation.h" - -namespace blender::compositor { - -CropBaseOperation::CropBaseOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_output_socket(DataType::Color); - settings_ = nullptr; - flags_.can_be_constant = true; -} - -void CropBaseOperation::update_area() -{ - const NodeTwoXYs &node_two_xys = *settings_; - const SocketReader *input = this->get_input_socket_reader(0); - const int2 input_size = int2(input->get_width(), input->get_height()); - if (relative_) { - /* The cropping bounds are relative to the image size. The factors are in the [0, 1] range, - * so it is guaranteed that they won't go over the input image size. */ - xmin_ = input_size.x * node_two_xys.fac_x1; - ymin_ = input_size.y * node_two_xys.fac_y2; - xmax_ = input_size.x * node_two_xys.fac_x2; - ymax_ = input_size.y * node_two_xys.fac_y1; - } - else { - /* Make sure the bounds don't go over the input image size. */ - xmin_ = min_ii(node_two_xys.x1, input_size.x); - ymin_ = min_ii(node_two_xys.y2, input_size.y); - xmax_ = min_ii(node_two_xys.x2, input_size.x); - ymax_ = min_ii(node_two_xys.y1, input_size.y); - } - - /* Make sure upper bound is actually higher than the lower bound. */ - xmin_ = min_ii(xmin_, xmax_); - ymin_ = min_ii(ymin_, ymax_); - xmax_ = max_ii(xmin_, xmax_); - ymax_ = max_ii(ymin_, ymax_); -} - -void CropBaseOperation::init_execution() -{ - update_area(); -} - -CropOperation::CropOperation() : CropBaseOperation() -{ - /* pass */ -} - -void CropOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - if ((it.x < xmax_ && it.x >= xmin_) && (it.y < ymax_ && it.y >= ymin_)) { - copy_v4_v4(it.out, it.in(0)); - } - else { - zero_v4(it.out); - } - } -} - -CropImageOperation::CropImageOperation() : CropBaseOperation() -{ - /* pass */ -} - -void CropImageOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmax = output_area.xmax + xmin_; - r_input_area.xmin = output_area.xmin + xmin_; - r_input_area.ymax = output_area.ymax + ymin_; - r_input_area.ymin = output_area.ymin + ymin_; -} - -void CropImageOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - NodeOperation::determine_canvas(preferred_area, r_area); - update_area(); - r_area.xmax = r_area.xmin + (xmax_ - xmin_); - r_area.ymax = r_area.ymin + (ymax_ - ymin_); -} - -void CropImageOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - const int width = get_width(); - const int height = get_height(); - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - if (it.x >= 0 && it.x < width && it.y >= 0 && it.y < height) { - input->read_elem_checked(it.x + xmin_, it.y + ymin_, it.out); - } - else { - zero_v4(it.out); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h deleted file mode 100644 index 55cad40f52b..00000000000 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class CropBaseOperation : public MultiThreadedOperation { - protected: - NodeTwoXYs *settings_; - bool relative_; - int xmax_; - int xmin_; - int ymax_; - int ymin_; - - void update_area(); - - public: - CropBaseOperation(); - void init_execution() override; - void set_crop_settings(NodeTwoXYs *settings) - { - settings_ = settings; - } - void set_relative(bool rel) - { - relative_ = rel; - } -}; - -class CropOperation : public CropBaseOperation { - private: - public: - CropOperation(); - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class CropImageOperation : public CropBaseOperation { - private: - public: - CropImageOperation(); - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cc b/source/blender/compositor/operations/COM_CryptomatteOperation.cc deleted file mode 100644 index 99a5674897c..00000000000 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-FileCopyrightText: 2018 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CryptomatteOperation.h" - -namespace blender::compositor { - -CryptomatteOperation::CryptomatteOperation(size_t num_inputs) -{ - inputs.resize(num_inputs); - for (size_t i = 0; i < num_inputs; i++) { - this->add_input_socket(DataType::Color); - } - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void CryptomatteOperation::init_execution() -{ - for (size_t i = 0; i < inputs.size(); i++) { - inputs[i] = this->get_input_socket_reader(i); - } -} - -void CryptomatteOperation::add_object_index(float object_index) -{ - if (object_index != 0.0f) { - object_index_.append(object_index); - } -} - -void CryptomatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - zero_v4(it.out); - for (int i = 0; i < it.get_num_inputs(); i++) { - const float *input = it.in(i); - if (i == 0) { - /* Write the front-most object as false color for picking. */ - it.out[0] = input[0]; - uint32_t m3hash; - ::memcpy(&m3hash, &input[0], sizeof(uint32_t)); - /* Since the red channel is likely to be out of display range, - * setting green and blue gives more meaningful images. */ - it.out[1] = (float(m3hash << 8) / float(UINT32_MAX)); - it.out[2] = (float(m3hash << 16) / float(UINT32_MAX)); - } - for (const float hash : object_index_) { - if (input[0] == hash) { - it.out[3] += input[1]; - } - if (input[2] == hash) { - it.out[3] += input[3]; - } - } - } - } -} - -CryptomattePickOperation::CryptomattePickOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); -} - -void CryptomattePickOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - copy_v3_v3(it.out, color); - it.out[3] = 1.0f; - } -} - -std::unique_ptr CryptomattePickOperation::get_meta_data() -{ - std::unique_ptr meta_data = std::make_unique(); - meta_data->is_data = true; - return meta_data; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.h b/source/blender/compositor/operations/COM_CryptomatteOperation.h deleted file mode 100644 index 4becec666de..00000000000 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-FileCopyrightText: 2018 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class CryptomatteOperation : public MultiThreadedOperation { - private: - Vector object_index_; - - public: - Vector inputs; - - CryptomatteOperation(size_t num_inputs = 6); - - void init_execution() override; - - void add_object_index(float object_index); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class CryptomattePickOperation : public MultiThreadedOperation { - public: - CryptomattePickOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - std::unique_ptr get_meta_data() override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cc b/source/blender/compositor/operations/COM_CurveBaseOperation.cc deleted file mode 100644 index b5280ab9b9b..00000000000 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_CurveBaseOperation.h" - -#include "BKE_colortools.hh" - -namespace blender::compositor { - -CurveBaseOperation::CurveBaseOperation() -{ - curve_mapping_ = nullptr; - flags_.can_be_constant = true; -} - -CurveBaseOperation::~CurveBaseOperation() -{ - if (curve_mapping_) { - BKE_curvemapping_free(curve_mapping_); - curve_mapping_ = nullptr; - } -} - -void CurveBaseOperation::init_execution() -{ - BKE_curvemapping_init(curve_mapping_); -} -void CurveBaseOperation::deinit_execution() -{ - if (curve_mapping_) { - BKE_curvemapping_free(curve_mapping_); - curve_mapping_ = nullptr; - } -} - -void CurveBaseOperation::set_curve_mapping(const CurveMapping *mapping) -{ - /* duplicate the curve to avoid glitches while drawing, see bug #32374. */ - if (curve_mapping_) { - BKE_curvemapping_free(curve_mapping_); - } - curve_mapping_ = BKE_curvemapping_copy(mapping); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h deleted file mode 100644 index 432ef9a823d..00000000000 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -struct CurveMapping; - -namespace blender::compositor { - -class CurveBaseOperation : public MultiThreadedOperation { - protected: - CurveMapping *curve_mapping_; - - public: - CurveBaseOperation(); - ~CurveBaseOperation(); - - void init_execution() override; - void deinit_execution() override; - - void set_curve_mapping(const CurveMapping *mapping); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cc b/source/blender/compositor/operations/COM_DenoiseOperation.cc deleted file mode 100644 index c11f798fad4..00000000000 --- a/source/blender/compositor/operations/COM_DenoiseOperation.cc +++ /dev/null @@ -1,244 +0,0 @@ -/* SPDX-FileCopyrightText: 2019 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DenoiseOperation.h" -#include "BLI_system.h" -#ifdef WITH_OPENIMAGEDENOISE -# include "BLI_threads.h" -# include -static pthread_mutex_t oidn_lock = BLI_MUTEX_INITIALIZER; -#endif - -namespace blender::compositor { - -bool COM_is_denoise_supported() -{ -#ifdef WITH_OPENIMAGEDENOISE -# ifdef __APPLE__ - /* Always supported through Accelerate framework BNNS on macOS. */ - return true; -# elif defined(__aarch64__) || defined(_M_ARM64) - /* OIDN 2.2 and up supports ARM64 on Windows and Linux. */ - return true; -# else - return BLI_cpu_support_sse42(); -# endif - -#else - return false; -#endif -} - -#ifdef WITH_OPENIMAGEDENOISE -static bool oidn_progress_monitor_function(void *user_ptr, double /*n*/) -{ - const NodeOperation *operation = static_cast(user_ptr); - return !operation->is_braked(); -} -#endif - -class DenoiseFilter { - private: -#ifdef WITH_OPENIMAGEDENOISE - oidn::DeviceRef device_; - oidn::FilterRef filter_; - bool initialized_ = false; -#endif - - public: -#ifdef WITH_OPENIMAGEDENOISE - ~DenoiseFilter() - { - BLI_assert(!initialized_); - } - - void init_and_lock_denoiser(NodeOperation *operation, MemoryBuffer *output) - { - /* Since it's memory intensive, it's better to run only one instance of OIDN at a time. - * OpenImageDenoise is multithreaded internally and should use all available cores - * nonetheless. */ - BLI_mutex_lock(&oidn_lock); - - device_ = oidn::newDevice(oidn::DeviceType::CPU); - device_.set("setAffinity", false); - device_.commit(); - filter_ = device_.newFilter("RT"); - filter_.setProgressMonitorFunction(oidn_progress_monitor_function, operation); - initialized_ = true; - set_image("output", output); - } - - void deinit_and_unlock_denoiser() - { - BLI_mutex_unlock(&oidn_lock); - initialized_ = false; - } - - void set_image(const StringRef name, MemoryBuffer *buffer) - { - BLI_assert(initialized_); - BLI_assert(!buffer->is_a_single_elem()); - filter_.setImage(name.data(), - buffer->get_buffer(), - oidn::Format::Float3, - buffer->get_width(), - buffer->get_height(), - 0, - buffer->get_elem_bytes_len()); - } - - template void set(const StringRef option_name, T value) - { - BLI_assert(initialized_); - filter_.set(option_name.data(), value); - } - - void execute() - { - BLI_assert(initialized_); - filter_.commit(); - filter_.execute(); - } - -#else - void init_and_lock_denoiser(NodeOperation * /*operation*/, MemoryBuffer * /*output*/) {} - - void deinit_and_unlock_denoiser() {} - - void set_image(const StringRef /*name*/, MemoryBuffer * /*buffer*/) {} - - template void set(const StringRef /*option_name*/, T /*value*/) {} - - void execute() {} -#endif -}; - -DenoiseBaseOperation::DenoiseBaseOperation() -{ - flags_.can_be_constant = true; - output_rendered_ = false; -} - -void DenoiseBaseOperation::get_area_of_interest(const int /*input_idx*/, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - r_input_area = this->get_canvas(); -} - -DenoiseOperation::DenoiseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Vector); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - settings_ = nullptr; -} - -static bool are_guiding_passes_noise_free(const NodeDenoise *settings) -{ - switch (settings->prefilter) { - case CMP_NODE_DENOISE_PREFILTER_NONE: - case CMP_NODE_DENOISE_PREFILTER_ACCURATE: /* Prefiltered with #DenoisePrefilterOperation. */ - return true; - case CMP_NODE_DENOISE_PREFILTER_FAST: - default: - return false; - } -} - -void DenoiseOperation::hash_output_params() -{ - if (settings_) { - hash_params(int(settings_->hdr), are_guiding_passes_noise_free(settings_)); - } -} - -void DenoiseOperation::generate_denoise(MemoryBuffer *output, - MemoryBuffer *input_color, - MemoryBuffer *input_normal, - MemoryBuffer *input_albedo, - const NodeDenoise *settings) -{ - if (input_color->is_a_single_elem()) { - output->fill(output->get_rect(), input_color->get_elem(0, 0)); - return; - } - - BLI_assert(COM_is_denoise_supported()); - - DenoiseFilter filter; - filter.init_and_lock_denoiser(this, output); - - filter.set_image("color", input_color); - if (!input_albedo->is_a_single_elem()) { - filter.set_image("albedo", input_albedo); - if (!input_normal->is_a_single_elem()) { - filter.set_image("normal", input_normal); - } - } - - BLI_assert(settings); - if (settings) { - filter.set("hdr", settings->hdr); - filter.set("srgb", false); - filter.set("cleanAux", are_guiding_passes_noise_free(settings)); - } - - filter.execute(); - filter.deinit_and_unlock_denoiser(); - - /* Copy the alpha channel, OpenImageDenoise currently only supports RGB. */ - output->copy_from(input_color, input_color->get_rect(), 3, COM_DATA_TYPE_VALUE_CHANNELS, 3); -} - -void DenoiseOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - if (!output_rendered_) { - this->generate_denoise(output, inputs[0], inputs[1], inputs[2], settings_); - output_rendered_ = true; - } -} - -DenoisePrefilterOperation::DenoisePrefilterOperation(DataType data_type) -{ - this->add_input_socket(data_type); - this->add_output_socket(data_type); - image_name_ = ""; -} - -void DenoisePrefilterOperation::hash_output_params() -{ - hash_param(image_name_); -} - -void DenoisePrefilterOperation::generate_denoise(MemoryBuffer *output, MemoryBuffer *input) -{ - if (input->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input->get_elem(0, 0)); - return; - } - - BLI_assert(COM_is_denoise_supported()); - - DenoiseFilter filter; - filter.init_and_lock_denoiser(this, output); - filter.set_image(image_name_, input); - filter.execute(); - filter.deinit_and_unlock_denoiser(); -} - -void DenoisePrefilterOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - if (!output_rendered_) { - this->generate_denoise(output, inputs[0]); - output_rendered_ = true; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.h b/source/blender/compositor/operations/COM_DenoiseOperation.h deleted file mode 100644 index 4aa4a1eb6c8..00000000000 --- a/source/blender/compositor/operations/COM_DenoiseOperation.h +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-FileCopyrightText: 2019 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -bool COM_is_denoise_supported(); - -class DenoiseBaseOperation : public NodeOperation { - protected: - bool output_rendered_; - - protected: - DenoiseBaseOperation(); - - public: - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; -}; - -class DenoiseOperation : public DenoiseBaseOperation { - private: - /** - * \brief settings of the denoise node. - */ - const NodeDenoise *settings_; - - public: - DenoiseOperation(); - - void set_denoise_settings(const NodeDenoise *settings) - { - settings_ = settings; - } - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - protected: - void hash_output_params() override; - void generate_denoise(MemoryBuffer *output, - MemoryBuffer *input_color, - MemoryBuffer *input_normal, - MemoryBuffer *input_albedo, - const NodeDenoise *settings); -}; - -class DenoisePrefilterOperation : public DenoiseBaseOperation { - private: - std::string image_name_; - - public: - DenoisePrefilterOperation(DataType data_type); - - void set_image_name(StringRef name) - { - image_name_ = name; - } - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - protected: - void hash_output_params() override; - - private: - void generate_denoise(MemoryBuffer *output, MemoryBuffer *input); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc deleted file mode 100644 index 0dc4f72dfc4..00000000000 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "MEM_guardedalloc.h" - -#include "COM_DespeckleOperation.h" - -namespace blender::compositor { - -DespeckleOperation::DespeckleOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - flags_.can_be_constant = true; -} - -BLI_INLINE int color_diff(const float a[3], const float b[3], const float threshold) -{ - return ((fabsf(a[0] - b[0]) > threshold) || (fabsf(a[1] - b[1]) > threshold) || - (fabsf(a[2] - b[2]) > threshold)); -} - -void DespeckleOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: { - const int add_x = 2; //(filter_width_ - 1) / 2 + 1; - const int add_y = 2; //(filter_height_ - 1) / 2 + 1; - r_input_area.xmin = output_area.xmin - add_x; - r_input_area.xmax = output_area.xmax + add_x; - r_input_area.ymin = output_area.ymin - add_y; - r_input_area.ymax = output_area.ymax + add_y; - break; - } - case FACTOR_INPUT_INDEX: { - r_input_area = output_area; - break; - } - } -} - -void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX]; - const int last_x = get_width() - 1; - const int last_y = get_height() - 1; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int x1 = std::max(it.x - 1, 0); - const int x2 = it.x; - const int x3 = std::min(it.x + 1, last_x); - const int y1 = std::max(it.y - 1, 0); - const int y2 = it.y; - const int y3 = std::min(it.y + 1, last_y); - - float w = 0.0f; - const float *color_org = it.in(IMAGE_INPUT_INDEX); - float color_mid[4]; - float color_mid_ok[4]; - const float *in1 = nullptr; - -#define TOT_DIV_ONE 1.0f -#define TOT_DIV_CNR float(M_SQRT1_2) - -#define WTOT (TOT_DIV_ONE * 4 + TOT_DIV_CNR * 4) - -#define COLOR_ADD(fac) \ - { \ - madd_v4_v4fl(color_mid, in1, fac); \ - if (color_diff(in1, color_org, threshold_)) { \ - w += fac; \ - madd_v4_v4fl(color_mid_ok, in1, fac); \ - } \ - } - - zero_v4(color_mid); - zero_v4(color_mid_ok); - - in1 = image->get_elem(x1, y1); - COLOR_ADD(TOT_DIV_CNR) - in1 = image->get_elem(x2, y1); - COLOR_ADD(TOT_DIV_ONE) - in1 = image->get_elem(x3, y1); - COLOR_ADD(TOT_DIV_CNR) - in1 = image->get_elem(x1, y2); - COLOR_ADD(TOT_DIV_ONE) - -#if 0 - const float *in2 = image->get_elem(x2, y2); - madd_v4_v4fl(color_mid, in2, filter_[4]); -#endif - - in1 = image->get_elem(x3, y2); - COLOR_ADD(TOT_DIV_ONE) - in1 = image->get_elem(x1, y3); - COLOR_ADD(TOT_DIV_CNR) - in1 = image->get_elem(x2, y3); - COLOR_ADD(TOT_DIV_ONE) - in1 = image->get_elem(x3, y3); - COLOR_ADD(TOT_DIV_CNR) - - mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2)))); - // mul_v4_fl(color_mid, 1.0f / w); - - if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) && - color_diff(color_mid, color_org, threshold_)) - { - const float factor = *it.in(FACTOR_INPUT_INDEX); - mul_v4_fl(color_mid_ok, 1.0f / w); - interp_v4_v4v4(it.out, color_org, color_mid_ok, factor); - } - else { - copy_v4_v4(it.out, color_org); - } - -#undef TOT_DIV_ONE -#undef TOT_DIV_CNR -#undef WTOT -#undef COLOR_ADD - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h deleted file mode 100644 index b0c307f9d92..00000000000 --- a/source/blender/compositor/operations/COM_DespeckleOperation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DespeckleOperation : public MultiThreadedOperation { - private: - constexpr static int IMAGE_INPUT_INDEX = 0; - constexpr static int FACTOR_INPUT_INDEX = 1; - - float threshold_; - float threshold_neighbor_; - - // int filter_width_; - // int filter_height_; - - public: - DespeckleOperation(); - - void set_threshold(float threshold) - { - threshold_ = threshold; - } - void set_threshold_neighbor(float threshold) - { - threshold_neighbor_ = threshold; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cc b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cc deleted file mode 100644 index 0b4bfd511bd..00000000000 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DifferenceMatteOperation.h" - -namespace blender::compositor { - -DifferenceMatteOperation::DifferenceMatteOperation() -{ - add_input_socket(DataType::Color); - add_input_socket(DataType::Color); - add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -void DifferenceMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color1 = it.in(0); - const float *color2 = it.in(1); - - float difference = (fabsf(color2[0] - color1[0]) + fabsf(color2[1] - color1[1]) + - fabsf(color2[2] - color1[2])); - - /* Average together the distances. */ - difference = difference / 3.0f; - - const float tolerance = settings_->t1; - const float falloff = settings_->t2; - - /* Make 100% transparent. */ - if (difference <= tolerance) { - it.out[0] = 0.0f; - } - /* In the falloff region, make partially transparent. */ - else if (difference <= falloff + tolerance) { - difference = difference - tolerance; - const float alpha = difference / falloff; - /* Only change if more transparent than before. */ - if (alpha < color1[3]) { - it.out[0] = alpha; - } - else { /* Leave as before. */ - it.out[0] = color1[3]; - } - } - else { - /* Foreground object. */ - it.out[0] = color1[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h deleted file mode 100644 index ab306d95249..00000000000 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class DifferenceMatteOperation : public MultiThreadedOperation { - private: - NodeChroma *settings_; - - public: - DifferenceMatteOperation(); - - void set_settings(NodeChroma *node_chroma) - { - settings_ = node_chroma; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cc b/source/blender/compositor/operations/COM_DilateErodeOperation.cc deleted file mode 100644 index e2b2f0696fa..00000000000 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cc +++ /dev/null @@ -1,407 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DilateErodeOperation.h" - -namespace blender::compositor { - -DilateErodeThresholdOperation::DilateErodeThresholdOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - flags_.can_be_constant = true; - inset_ = 0.0f; - switch_ = 0.5f; - distance_ = 0.0f; -} - -void DilateErodeThresholdOperation::init_data() -{ - if (distance_ < 0.0f) { - scope_ = -distance_ + inset_; - } - else { - if (inset_ * 2 > distance_) { - scope_ = std::max(inset_ * 2 - distance_, distance_); - } - else { - scope_ = distance_; - } - } - if (scope_ < 3) { - scope_ = 3; - } -} - -void DilateErodeThresholdOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = output_area.xmin - scope_; - r_input_area.xmax = output_area.xmax + scope_; - r_input_area.ymin = output_area.ymin - scope_; - r_input_area.ymax = output_area.ymax + scope_; -} - -struct DilateErodeThresholdOperation::PixelData { - int x; - int y; - int xmin; - int xmax; - int ymin; - int ymax; - const float *elem; - float distance; - int elem_stride; - int row_stride; - /** Switch. */ - float sw; -}; - -template typename TCompare> -static float get_min_distance(DilateErodeThresholdOperation::PixelData &p) -{ - /* TODO(manzanilla): bad performance, generate a table with relative offsets on operation - * initialization to loop from less to greater distance and break as soon as #compare is - * true. */ - const TCompare compare; - float min_dist = p.distance; - const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride + - (intptr_t(p.xmin) - p.x) * p.elem_stride; - for (int yi = p.ymin; yi < p.ymax; yi++) { - const float dy = yi - p.y; - const float dist_y = dy * dy; - const float *elem = row; - for (int xi = p.xmin; xi < p.xmax; xi++) { - if (compare(*elem, p.sw)) { - const float dx = xi - p.x; - const float dist = dx * dx + dist_y; - min_dist = std::min(min_dist, dist); - } - elem += p.elem_stride; - } - row += p.row_stride; - } - return min_dist; -} - -void DilateErodeThresholdOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - const rcti &input_rect = input->get_rect(); - const float rd = scope_ * scope_; - const float inset = inset_; - - PixelData p; - p.sw = switch_; - p.distance = rd * 2; - p.elem_stride = input->elem_stride; - p.row_stride = input->row_stride; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - p.x = it.x; - p.y = it.y; - p.xmin = std::max(p.x - scope_, input_rect.xmin); - p.ymin = std::max(p.y - scope_, input_rect.ymin); - p.xmax = std::min(p.x + scope_, input_rect.xmax); - p.ymax = std::min(p.y + scope_, input_rect.ymax); - p.elem = it.in(0); - - float pixel_value; - if (*p.elem > p.sw) { - pixel_value = -sqrtf(get_min_distance(p)); - } - else { - pixel_value = sqrtf(get_min_distance(p)); - } - - if (distance_ > 0.0f) { - const float delta = distance_ - pixel_value; - if (delta >= 0.0f) { - *it.out = delta >= inset ? 1.0f : delta / inset; - } - else { - *it.out = 0.0f; - } - } - else { - const float delta = -distance_ + pixel_value; - if (delta < 0.0f) { - *it.out = delta < -inset ? 1.0f : (-delta) / inset; - } - else { - *it.out = 0.0f; - } - } - } -} - -DilateDistanceOperation::DilateDistanceOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - distance_ = 0.0f; - flags_.can_be_constant = true; -} - -void DilateDistanceOperation::init_data() -{ - scope_ = distance_; - if (scope_ < 3) { - scope_ = 3; - } -} - -void DilateDistanceOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = output_area.xmin - scope_; - r_input_area.xmax = output_area.xmax + scope_; - r_input_area.ymin = output_area.ymin - scope_; - r_input_area.ymax = output_area.ymax + scope_; -} - -struct DilateDistanceOperation::PixelData { - int x; - int y; - int xmin; - int xmax; - int ymin; - int ymax; - const float *elem; - float min_distance; - int scope; - int elem_stride; - int row_stride; - const rcti &input_rect; - - PixelData(MemoryBuffer *input, const int distance, const int scope) - : min_distance(distance * distance), - scope(scope), - elem_stride(input->elem_stride), - row_stride(input->row_stride), - input_rect(input->get_rect()) - { - } - - void update(BuffersIterator &it) - { - x = it.x; - y = it.y; - xmin = std::max(x - scope, input_rect.xmin); - ymin = std::max(y - scope, input_rect.ymin); - xmax = std::min(x + scope, input_rect.xmax); - ymax = std::min(y + scope, input_rect.ymax); - elem = it.in(0); - } -}; - -template typename TCompare> -static float get_distance_value(DilateDistanceOperation::PixelData &p, const float start_value) -{ - /* TODO(manzanilla): bad performance, only loop elements within minimum distance removing - * coordinates and conditional if `dist <= min_dist`. May need to generate a table of offsets. */ - const TCompare compare; - const float min_dist = p.min_distance; - float value = start_value; - const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride + - (intptr_t(p.xmin) - p.x) * p.elem_stride; - for (int yi = p.ymin; yi < p.ymax; yi++) { - const float dy = yi - p.y; - const float dist_y = dy * dy; - const float *elem = row; - for (int xi = p.xmin; xi < p.xmax; xi++) { - const float dx = xi - p.x; - const float dist = dx * dx + dist_y; - if (dist <= min_dist) { - value = compare(*elem, value) ? *elem : value; - } - elem += p.elem_stride; - } - row += p.row_stride; - } - - return value; -} - -void DilateDistanceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - PixelData p(inputs[0], distance_, scope_); - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - p.update(it); - *it.out = get_distance_value(p, 0.0f); - } -} - -ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation() -{ - /* pass */ -} - -void ErodeDistanceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - PixelData p(inputs[0], distance_, scope_); - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - p.update(it); - *it.out = get_distance_value(p, 1.0f); - } -} - -DilateStepOperation::DilateStepOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); -} - -void DilateStepOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = output_area.xmin - iterations_; - r_input_area.xmax = output_area.xmax + iterations_; - r_input_area.ymin = output_area.ymin - iterations_; - r_input_area.ymax = output_area.ymax + iterations_; -} - -template -static void step_update_memory_buffer(MemoryBuffer *output, - const MemoryBuffer *input, - const rcti &area, - const int num_iterations, - const float compare_min_value) -{ - TCompareSelector selector; - - const int width = output->get_width(); - const int height = output->get_height(); - - const int half_window = num_iterations; - const int window = half_window * 2 + 1; - - const int xmin = std::max(0, area.xmin - half_window); - const int ymin = std::max(0, area.ymin - half_window); - const int xmax = std::min(width, area.xmax + half_window); - const int ymax = std::min(height, area.ymax + half_window); - - const int bwidth = area.xmax - area.xmin; - const int bheight = area.ymax - area.ymin; - - /* NOTE: #result has area width, but new height. - * We have to calculate the additional rows in the first pass, - * to have valid data available for the second pass. */ - rcti result_area; - BLI_rcti_init(&result_area, area.xmin, area.xmax, ymin, ymax); - MemoryBuffer result(DataType::Value, result_area); - - /* #temp holds maxima for every step in the algorithm, #buf holds a - * single row or column of input values, padded with #limit values to - * simplify the logic. */ - float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp"); - float *buf = (float *)MEM_mallocN(sizeof(float) * (std::max(bwidth, bheight) + 5 * half_window), - "dilate erode buf"); - - /* The following is based on the van Herk/Gil-Werman algorithm for morphology operations. */ - /* First pass, horizontal dilate/erode. */ - for (int y = ymin; y < ymax; y++) { - for (int x = 0; x < bwidth + 5 * half_window; x++) { - buf[x] = compare_min_value; - } - for (int x = xmin; x < xmax; x++) { - buf[x - area.xmin + window - 1] = input->get_value(x, y, 0); - } - - for (int i = 0; i < (bwidth + 3 * half_window) / window; i++) { - int start = (i + 1) * window - 1; - - temp[window - 1] = buf[start]; - for (int x = 1; x < window; x++) { - temp[window - 1 - x] = selector(temp[window - x], buf[start - x]); - temp[window - 1 + x] = selector(temp[window + x - 2], buf[start + x]); - } - - start = half_window + (i - 1) * window + 1; - for (int x = -std::min(0, start); x < window - std::max(0, start + window - bwidth); x++) { - result.get_value(start + x + area.xmin, y, 0) = selector(temp[x], temp[x + window - 1]); - } - } - } - - /* Second pass, vertical dilate/erode. */ - for (int x = 0; x < bwidth; x++) { - for (int y = 0; y < bheight + 5 * half_window; y++) { - buf[y] = compare_min_value; - } - for (int y = ymin; y < ymax; y++) { - buf[y - area.ymin + window - 1] = result.get_value(x + area.xmin, y, 0); - } - - for (int i = 0; i < (bheight + 3 * half_window) / window; i++) { - int start = (i + 1) * window - 1; - - temp[window - 1] = buf[start]; - for (int y = 1; y < window; y++) { - temp[window - 1 - y] = selector(temp[window - y], buf[start - y]); - temp[window - 1 + y] = selector(temp[window + y - 2], buf[start + y]); - } - - start = half_window + (i - 1) * window + 1; - for (int y = -std::min(0, start); y < window - std::max(0, start + window - bheight); y++) { - result.get_value(x + area.xmin, y + start + area.ymin, 0) = selector(temp[y], - temp[y + window - 1]); - } - } - } - - MEM_freeN(temp); - MEM_freeN(buf); - - output->copy_from(&result, area); -} - -struct Max2Selector { - float operator()(float f1, float f2) const - { - return std::max(f1, f2); - } -}; - -void DilateStepOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - step_update_memory_buffer(output, inputs[0], area, iterations_, -FLT_MAX); -} - -ErodeStepOperation::ErodeStepOperation() : DilateStepOperation() -{ - /* pass */ -} - -struct Min2Selector { - float operator()(float f1, float f2) const - { - return std::min(f1, f2); - } -}; - -void ErodeStepOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - step_update_memory_buffer(output, inputs[0], area, iterations_, FLT_MAX); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h deleted file mode 100644 index 15895a40da6..00000000000 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DilateErodeThresholdOperation : public MultiThreadedOperation { - public: - struct PixelData; - - private: - float distance_; - float switch_; - float inset_; - - /** - * determines the area of interest to track pixels - * keep this one as small as possible for speed gain. - */ - int scope_; - - public: - /* DilateErode Distance Threshold */ - DilateErodeThresholdOperation(); - - void init_data() override; - - void set_distance(float distance) - { - distance_ = distance; - } - void set_switch(float sw) - { - switch_ = sw; - } - void set_inset(float inset) - { - inset_ = inset; - } - - 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 inputs) override; -}; - -class DilateDistanceOperation : public MultiThreadedOperation { - public: - struct PixelData; - - protected: - float distance_; - int scope_; - - public: - /* Dilate Distance. */ - DilateDistanceOperation(); - - void init_data() override; - - void set_distance(float distance) - { - distance_ = distance; - } - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final; - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class ErodeDistanceOperation : public DilateDistanceOperation { - public: - /* Erode Distance */ - ErodeDistanceOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class DilateStepOperation : public MultiThreadedOperation { - protected: - int iterations_; - - public: - /* Dilate step */ - DilateStepOperation(); - - void set_iterations(int iterations) - { - iterations_ = iterations; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final; - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class ErodeStepOperation : public DilateStepOperation { - public: - /** Erode step. */ - ErodeStepOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc deleted file mode 100644 index 6c1d3c29eee..00000000000 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DirectionalBlurOperation.h" - -namespace blender::compositor { - -DirectionalBlurOperation::DirectionalBlurOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void DirectionalBlurOperation::init_execution() -{ - const float angle = data_->angle; - const float zoom = data_->zoom; - const float spin = data_->spin; - const float iterations = data_->iter; - const float distance = data_->distance; - const float center_x = data_->center_x; - const float center_y = data_->center_y; - const float width = get_width(); - const float height = get_height(); - - const float a = angle; - const float itsc = 1.0f / powf(2.0f, float(iterations)); - float D; - - D = distance * sqrtf(width * width + height * height); - center_x_pix_ = center_x * width; - center_y_pix_ = center_y * height; - - tx_ = itsc * D * cosf(a); - ty_ = -itsc * D * sinf(a); - sc_ = itsc * zoom; - rot_ = itsc * spin; -} - -void DirectionalBlurOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area = this->get_canvas(); -} - -void DirectionalBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - const int iterations = pow(2.0f, data_->iter); - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - float color_accum[4]; - input->read_elem_bilinear(x, y, color_accum); - - /* Blur pixel. */ - /* TODO(manzanilla): Many values used on iterations can be calculated beforehand. Create a - * table on operation initialization. */ - float ltx = tx_; - float lty = ty_; - float lsc = sc_; - float lrot = rot_; - for (int i = 0; i < iterations; i++) { - const float cs = cosf(lrot), ss = sinf(lrot); - const float isc = 1.0f / (1.0f + lsc); - - const float v = isc * (y + 0.5f - center_y_pix_) + lty; - const float u = isc * (x + 0.5f - center_x_pix_) + ltx; - - float color[4]; - input->read_elem_bilinear( - cs * u + ss * v + center_x_pix_ - 0.5f, cs * v - ss * u + center_y_pix_ - 0.5f, color); - add_v4_v4(color_accum, color); - - /* Double transformations. */ - ltx += tx_; - lty += ty_; - lrot += rot_; - lsc += sc_; - } - - mul_v4_v4fl(it.out, color_accum, 1.0f / (iterations + 1)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h b/source/blender/compositor/operations/COM_DirectionalBlurOperation.h deleted file mode 100644 index 0ee99cf3b32..00000000000 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DirectionalBlurOperation : public MultiThreadedOperation { - private: - const NodeDBlurData *data_; - - float center_x_pix_, center_y_pix_; - float tx_, ty_; - float sc_, rot_; - - public: - DirectionalBlurOperation(); - - void init_execution() override; - - void set_data(const NodeDBlurData *data) - { - data_ = data; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc deleted file mode 100644 index 7be21ee796d..00000000000 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DisplaceOperation.h" - -namespace blender::compositor { - -DisplaceOperation::DisplaceOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Vector); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void DisplaceOperation::init_execution() -{ - NodeOperation *vector = this->get_input_socket_reader(1); - - width_x4_ = this->get_width() * 4; - height_x4_ = this->get_height() * 4; - input_vector_width_ = vector->get_width(); - input_vector_height_ = vector->get_height(); -} - -bool DisplaceOperation::read_displacement( - float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v) -{ - float width = input_vector_width_; - float height = input_vector_height_; - if (x < 0.0f || x >= width || y < 0.0f || y >= height) { - r_u = 0.0f; - r_v = 0.0f; - return false; - } - - float col[4]; - vector_read_fn_(x, y, col); - r_u = origin[0] - col[0] * xscale; - r_v = origin[1] - col[1] * yscale; - return true; -} - -void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float r_deriv[2][2]) -{ - float col[4]; - float uv[2]; /* temporary variables for derivative estimation */ - int num; - - scale_x_read_fn_(xy[0], xy[1], col); - float xs = col[0]; - scale_y_read_fn_(xy[0], xy[1], col); - float ys = col[0]; - /* clamp x and y displacement to triple image resolution - - * to prevent hangs from huge values mistakenly plugged in eg. z buffers */ - CLAMP(xs, -width_x4_, width_x4_); - CLAMP(ys, -height_x4_, height_x4_); - - /* displaced pixel in uv coords, for image sampling */ - read_displacement(xy[0], xy[1], xs, ys, xy, r_uv[0], r_uv[1]); - - /* Estimate partial derivatives using 1-pixel offsets */ - const float epsilon[2] = {1.0f, 1.0f}; - - zero_v2(r_deriv[0]); - zero_v2(r_deriv[1]); - - num = 0; - if (read_displacement(xy[0] + epsilon[0], xy[1], xs, ys, xy, uv[0], uv[1])) { - r_deriv[0][0] += uv[0] - r_uv[0]; - r_deriv[1][0] += uv[1] - r_uv[1]; - num++; - } - if (read_displacement(xy[0] - epsilon[0], xy[1], xs, ys, xy, uv[0], uv[1])) { - r_deriv[0][0] += r_uv[0] - uv[0]; - r_deriv[1][0] += r_uv[1] - uv[1]; - num++; - } - if (num > 0) { - float numinv = 1.0f / float(num); - r_deriv[0][0] *= numinv; - r_deriv[1][0] *= numinv; - } - - num = 0; - if (read_displacement(xy[0], xy[1] + epsilon[1], xs, ys, xy, uv[0], uv[1])) { - r_deriv[0][1] += uv[0] - r_uv[0]; - r_deriv[1][1] += uv[1] - r_uv[1]; - num++; - } - if (read_displacement(xy[0], xy[1] - epsilon[1], xs, ys, xy, uv[0], uv[1])) { - r_deriv[0][1] += r_uv[0] - uv[0]; - r_deriv[1][1] += r_uv[1] - uv[1]; - num++; - } - if (num > 0) { - float numinv = 1.0f / float(num); - r_deriv[0][1] *= numinv; - r_deriv[1][1] *= numinv; - } -} - -void DisplaceOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case 0: { - r_input_area = get_input_operation(input_idx)->get_canvas(); - break; - } - case 1: { - r_input_area = output_area; - expand_area_for_sampler(r_input_area, PixelSampler::Bilinear); - break; - } - default: { - r_input_area = output_area; - break; - } - } -} - -void DisplaceOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span inputs) -{ - MemoryBuffer *vector = inputs[1]; - MemoryBuffer *scale_x = inputs[2]; - MemoryBuffer *scale_y = inputs[3]; - vector_read_fn_ = [=](float x, float y, float *out) { vector->read_elem_bilinear(x, y, out); }; - scale_x_read_fn_ = [=](float x, float y, float *out) { scale_x->read_elem_checked(x, y, out); }; - scale_y_read_fn_ = [=](float x, float y, float *out) { scale_y->read_elem_checked(x, y, out); }; -} - -void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_color = inputs[0]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - const float xy[2] = {float(it.x), float(it.y)}; - float uv[2]; - float deriv[2][2]; - - pixel_transform(xy, uv, deriv); - if (is_zero_v2(deriv[0]) && is_zero_v2(deriv[1])) { - input_color->read_elem_bilinear(uv[0], uv[1], it.out); - } - else { - /* EWA filtering (without nearest it gets blurry with NO distortion). */ - input_color->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], false, it.out); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h deleted file mode 100644 index f8915c8888a..00000000000 --- a/source/blender/compositor/operations/COM_DisplaceOperation.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DisplaceOperation : public MultiThreadedOperation { - private: - float width_x4_; - float height_x4_; - - int input_vector_width_; - int input_vector_height_; - - std::function vector_read_fn_; - std::function scale_x_read_fn_; - std::function scale_y_read_fn_; - - public: - DisplaceOperation(); - - void pixel_transform(const float xy[2], float r_uv[2], float r_deriv[2][2]); - - void init_execution() override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - bool read_displacement( - float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cc b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cc deleted file mode 100644 index d36347dc358..00000000000 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DistanceRGBMatteOperation.h" - -namespace blender::compositor { - -DistanceRGBMatteOperation::DistanceRGBMatteOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -float DistanceRGBMatteOperation::calculate_distance(const float key[4], const float image[4]) -{ - return len_v3v3(key, image); -} - -void DistanceRGBMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *in_image = it.in(0); - const float *in_key = it.in(1); - - float distance = this->calculate_distance(in_key, in_image); - const float tolerance = settings_->t1; - const float falloff = settings_->t2; - - /* Store matte(alpha) value in [0] to go with - * COM_SetAlphaMultiplyOperation and the Value output. - */ - - /* Make 100% transparent. */ - if (distance < tolerance) { - it.out[0] = 0.0f; - } - /* In the falloff region, make partially transparent. */ - else if (distance < falloff + tolerance) { - distance = distance - tolerance; - const float alpha = distance / falloff; - /* Only change if more transparent than before. */ - if (alpha < in_image[3]) { - it.out[0] = alpha; - } - else { /* Leave as before. */ - it.out[0] = in_image[3]; - } - } - else { - /* Leave as before. */ - it.out[0] = in_image[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h deleted file mode 100644 index 1e7a4e86b7e..00000000000 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class DistanceRGBMatteOperation : public MultiThreadedOperation { - protected: - const NodeChroma *settings_; - - virtual float calculate_distance(const float key[4], const float image[4]); - - public: - DistanceRGBMatteOperation(); - - void set_settings(const NodeChroma *node_chroma) - { - settings_ = node_chroma; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cc b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cc deleted file mode 100644 index d62847eb792..00000000000 --- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DistanceYCCMatteOperation.h" - -namespace blender::compositor { - -float DistanceYCCMatteOperation::calculate_distance(const float key[4], const float image[4]) -{ - /* only measure the second 2 values */ - return len_v2v2(key + 1, image + 1); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h deleted file mode 100644 index beedb122d52..00000000000 --- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_DistanceRGBMatteOperation.h" -#include "COM_MixOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class DistanceYCCMatteOperation : public DistanceRGBMatteOperation { - protected: - float calculate_distance(const float key[4], const float image[4]) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cc b/source/blender/compositor/operations/COM_DotproductOperation.cc deleted file mode 100644 index 3c9720f2480..00000000000 --- a/source/blender/compositor/operations/COM_DotproductOperation.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_DotproductOperation.h" - -namespace blender::compositor { - -DotproductOperation::DotproductOperation() -{ - this->add_input_socket(DataType::Vector); - this->add_input_socket(DataType::Vector); - this->add_output_socket(DataType::Value); - this->set_canvas_input_index(0); - flags_.can_be_constant = true; -} - -void DotproductOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *input1 = it.in(0); - const float *input2 = it.in(1); - *it.out = -(input1[0] * input2[0] + input1[1] * input2[1] + input1[2] * input2[2]); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h deleted file mode 100644 index 640e986bec0..00000000000 --- a/source/blender/compositor/operations/COM_DotproductOperation.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DotproductOperation : public MultiThreadedOperation { - public: - DotproductOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc deleted file mode 100644 index 8dde0a06e34..00000000000 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc +++ /dev/null @@ -1,193 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "BLI_math_vector.hh" -#include "BLI_span.hh" -#include "BLI_task.hh" - -#include "COM_DoubleEdgeMaskOperation.h" -#include "COM_JumpFloodingAlgorithm.h" - -/* Exact copies of the functions in compositor_double_edge_mask_compute_boundary.glsl and - * compositor_double_edge_mask_compute_gradient.glsl but adapted for CPU. See those files for more - * information. */ - -namespace blender::compositor { - -static float load_mask(const float *input, int2 texel, int2 size) -{ - const int2 clamped_texel = math::clamp(texel, int2(0), size - 1); - return input[size_t(clamped_texel.y) * size.x + clamped_texel.x]; -} - -static float load_mask(const float *input, int2 texel, int2 size, float fallback) -{ - if (texel.x < 0 || texel.x >= size.x || texel.y < 0 || texel.y >= size.y) { - return fallback; - } - return input[size_t(texel.y) * size.x + texel.x]; -} - -void DoubleEdgeMaskOperation::compute_boundary(const float *inner_mask, - const float *outer_mask, - MutableSpan inner_boundary, - MutableSpan outer_boundary) -{ - const int2 size = int2(this->get_width(), this->get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - - bool has_inner_non_masked_neighbors = false; - bool has_outer_non_masked_neighbors = false; - for (int j = -1; j <= 1; j++) { - for (int i = -1; i <= 1; i++) { - int2 offset = int2(i, j); - - if (offset == int2(0)) { - continue; - } - - if (load_mask(inner_mask, texel + offset, size) == 0.0f) { - has_inner_non_masked_neighbors = true; - } - - float boundary_fallback = include_edges_of_image_ ? 0.0f : 1.0f; - if (load_mask(outer_mask, texel + offset, size, boundary_fallback) == 0.0f) { - has_outer_non_masked_neighbors = true; - } - - if (has_inner_non_masked_neighbors && has_outer_non_masked_neighbors) { - break; - } - } - } - - bool is_inner_masked = load_mask(inner_mask, texel, size) > 0.0f; - bool is_outer_masked = load_mask(outer_mask, texel, size) > 0.0f; - - bool is_inner_boundary = is_inner_masked && has_inner_non_masked_neighbors && - (is_outer_masked || include_all_inner_edges_); - bool is_outer_boundary = is_outer_masked && !is_inner_masked && - has_outer_non_masked_neighbors; - - int2 inner_jump_flooding_value = initialize_jump_flooding_value(texel, is_inner_boundary); - int2 outer_jump_flooding_value = initialize_jump_flooding_value(texel, is_outer_boundary); - - const size_t output_index = size_t(texel.y) * size.x + texel.x; - inner_boundary[output_index] = inner_jump_flooding_value; - outer_boundary[output_index] = outer_jump_flooding_value; - } - } - }); -} - -void DoubleEdgeMaskOperation::compute_gradient(const float *inner_mask_buffer, - const float *outer_mask_buffer, - MutableSpan flooded_inner_boundary, - MutableSpan flooded_outer_boundary, - float *output_mask) -{ - const int2 size = int2(this->get_width(), this->get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - const size_t index = size_t(texel.y) * size.x + texel.x; - - float inner_mask = inner_mask_buffer[index]; - if (inner_mask != 0.0f) { - output_mask[index] = 1.0f; - continue; - } - - float outer_mask = outer_mask_buffer[index]; - if (outer_mask == 0.0f) { - output_mask[index] = 0.0f; - continue; - } - - int2 inner_boundary_texel = flooded_inner_boundary[index]; - int2 outer_boundary_texel = flooded_outer_boundary[index]; - float distance_to_inner = math::distance(float2(texel), float2(inner_boundary_texel)); - float distance_to_outer = math::distance(float2(texel), float2(outer_boundary_texel)); - - float gradient = distance_to_outer / (distance_to_outer + distance_to_inner); - - output_mask[index] = gradient; - } - } - }); -} - -void DoubleEdgeMaskOperation::compute_double_edge_mask(const float *inner_mask, - const float *outer_mask, - float *output_mask) -{ - const int2 size = int2(this->get_width(), this->get_height()); - Array inner_boundary(size_t(size.x) * size.y); - Array outer_boundary(size_t(size.x) * size.y); - compute_boundary(inner_mask, outer_mask, inner_boundary, outer_boundary); - Array flooded_inner_boundary = jump_flooding(inner_boundary, size); - Array flooded_outer_boundary = jump_flooding(outer_boundary, size); - compute_gradient( - inner_mask, outer_mask, flooded_inner_boundary, flooded_outer_boundary, output_mask); -} - -DoubleEdgeMaskOperation::DoubleEdgeMaskOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - include_all_inner_edges_ = false; - include_edges_of_image_ = false; - flags_.can_be_constant = true; - is_output_rendered_ = false; -} - -void DoubleEdgeMaskOperation::get_area_of_interest(int /*input_idx*/, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - r_input_area = this->get_canvas(); -} - -void DoubleEdgeMaskOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - if (!is_output_rendered_) { - MemoryBuffer *input_inner_mask = inputs[0]; - MemoryBuffer *input_outer_mask = inputs[1]; - if (input_inner_mask->is_a_single_elem() && input_outer_mask->is_a_single_elem()) { - output->clear(); - is_output_rendered_ = true; - return; - } - - /* Ensure full buffers to work with no strides. */ - MemoryBuffer *inner_mask = input_inner_mask->is_a_single_elem() ? input_inner_mask->inflate() : - input_inner_mask; - MemoryBuffer *outer_mask = input_outer_mask->is_a_single_elem() ? input_outer_mask->inflate() : - input_outer_mask; - - BLI_assert(output->get_width() == this->get_width()); - BLI_assert(output->get_height() == this->get_height()); - compute_double_edge_mask( - inner_mask->get_buffer(), outer_mask->get_buffer(), output->get_buffer()); - is_output_rendered_ = true; - - if (inner_mask != input_inner_mask) { - delete inner_mask; - } - if (outer_mask != input_outer_mask) { - delete outer_mask; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h deleted file mode 100644 index cb1d2235538..00000000000 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_span.hh" - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class DoubleEdgeMaskOperation : public NodeOperation { - private: - bool include_all_inner_edges_; - bool include_edges_of_image_; - - bool is_output_rendered_; - - public: - DoubleEdgeMaskOperation(); - - void compute_boundary(const float *inner_mask, - const float *outer_mask, - MutableSpan inner_boundary, - MutableSpan outer_boundary); - - void compute_gradient(const float *inner_mask_buffer, - const float *outer_mask_buffer, - MutableSpan flooded_inner_boundary, - MutableSpan flooded_outer_boundary, - float *output_mask); - - void compute_double_edge_mask(const float *inner_mask, - const float *outer_mask, - float *output_mask); - - void set_include_all_inner_edges(bool include_all_inner_edges) - { - include_all_inner_edges_ = include_all_inner_edges; - } - void set_include_edges_of_image(bool include_edges_of_image) - { - include_edges_of_image_ = include_edges_of_image; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc deleted file mode 100644 index d257b47fb37..00000000000 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_EllipseMaskOperation.h" - -namespace blender::compositor { - -EllipseMaskOperation::EllipseMaskOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - cosine_ = 0.0f; - sine_ = 0.0f; -} -void EllipseMaskOperation::init_execution() -{ - const double rad = double(data_->rotation); - cosine_ = cos(rad); - sine_ = sin(rad); - aspect_ratio_ = float(this->get_width()) / this->get_height(); -} - -void EllipseMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MaskFunc mask_func; - switch (mask_type_) { - case CMP_NODE_MASKTYPE_ADD: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? std::max(mask[0], value[0]) : mask[0]; - }; - break; - case CMP_NODE_MASKTYPE_SUBTRACT: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? std::clamp(mask[0] - value[0], 0.0f, 1.0f) : mask[0]; - }; - break; - case CMP_NODE_MASKTYPE_MULTIPLY: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? mask[0] * value[0] : 0; - }; - break; - case CMP_NODE_MASKTYPE_NOT: - mask_func = [](const bool is_inside, const float *mask, const float *value) { - if (is_inside) { - return mask[0] > 0.0f ? 0.0f : value[0]; - } - return mask[0]; - }; - break; - } - apply_mask(output, area, inputs, mask_func); -} - -void EllipseMaskOperation::apply_mask(MemoryBuffer *output, - const rcti &area, - Span inputs, - MaskFunc mask_func) -{ - const MemoryBuffer *input_mask = inputs[0]; - const MemoryBuffer *input_value = inputs[1]; - const float op_last_x = std::max(this->get_width() - 1.0f, FLT_EPSILON); - const float op_last_y = std::max(this->get_height() - 1.0f, FLT_EPSILON); - const float half_w = data_->width / 2.0f; - const float half_h = data_->height / 2.0f; - const float tx = half_w * half_w; - const float ty = half_h * half_h; - for (int y = area.ymin; y < area.ymax; y++) { - const float op_ry = y / op_last_y; - const float dy = (op_ry - data_->y) / aspect_ratio_; - float *out = output->get_elem(area.xmin, y); - const float *mask = input_mask->get_elem(area.xmin, y); - const float *value = input_value->get_elem(area.xmin, y); - for (int x = area.xmin; x < area.xmax; x++) { - const float op_rx = x / op_last_x; - const float dx = op_rx - data_->x; - const float rx = data_->x + (cosine_ * dx + sine_ * dy); - const float ry = data_->y + (-sine_ * dx + cosine_ * dy); - float sx = rx - data_->x; - sx *= sx; - float sy = ry - data_->y; - sy *= sy; - const bool inside = ((sx / tx) + (sy / ty)) <= (1.0f + FLT_EPSILON); - out[0] = mask_func(inside, mask, value); - - mask += input_mask->elem_stride; - value += input_value->elem_stride; - out += output->elem_stride; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h deleted file mode 100644 index 19231971bd3..00000000000 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class EllipseMaskOperation : public MultiThreadedOperation { - private: - using MaskFunc = std::function; - - float sine_; - float cosine_; - float aspect_ratio_; - int mask_type_; - - NodeEllipseMask *data_; - - public: - EllipseMaskOperation(); - - void init_execution() override; - - void set_data(NodeEllipseMask *data) - { - data_ = data; - } - - void set_mask_type(int mask_type) - { - mask_type_ = mask_type; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - void apply_mask(MemoryBuffer *output, - const rcti &area, - Span inputs, - MaskFunc mask_func); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc deleted file mode 100644 index 37830ea31b8..00000000000 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "COM_FastGaussianBlurOperation.h" - -namespace blender::compositor { - -FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation(DataType::Color) -{ - iirgaus_ = nullptr; - data_.filtertype = R_FILTER_FAST_GAUSS; -} - -void FastGaussianBlurOperation::init_data() -{ - BlurBaseOperation::init_data(); - - /* Compute the Gaussian sigma from the radius, where the radius is in pixels. Blender's filter is - * truncated at |x| > 3 * sigma as can be seen in the R_FILTER_GAUSS case of the RE_filter_value - * function, so we divide by three to get the approximate sigma value. */ - sigma_x_ = data_.sizex * size_ / 3.0f; - sigma_y_ = data_.sizey * size_ / 3.0f; -} - -void FastGaussianBlurOperation::init_execution() -{ - BlurBaseOperation::init_execution(); -} - -void FastGaussianBlurOperation::deinit_execution() -{ - if (iirgaus_) { - delete iirgaus_; - iirgaus_ = nullptr; - } -} - -void FastGaussianBlurOperation::set_size(int size_x, int size_y) -{ - /* TODO: there should be a better way to use the operation without knowing specifics of the blur - * node (i.e. data_). We could use factory pattern to solve this problem. */ - data_.sizex = size_x; - data_.sizey = size_y; - sizeavailable_ = true; -} - -void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, uint chan, uint xy) -{ - BLI_assert(!src->is_a_single_elem()); - double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3]; - double *X, *Y, *W; - const uint src_width = src->get_width(); - const uint src_height = src->get_height(); - uint x, y, src_dim_max; - uint i; - float *buffer = src->get_buffer(); - const uint8_t num_channels = src->get_num_channels(); - - /* <0.5 not valid, though can have a possibly useful sort of sharpening effect. */ - if (sigma < 0.5f) { - return; - } - - if ((xy < 1) || (xy > 3)) { - xy = 3; - } - - /* XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels, - * so just skipping blur along faulty direction if src's def is below that limit! */ - if (src_width < 3) { - xy &= ~1; - } - if (src_height < 3) { - xy &= ~2; - } - if (xy < 1) { - return; - } - - /* See "Recursive Gabor Filtering" by Young/VanVliet - * all factors here in double-precision. - * Required, because for single-precision floating point seems to blow up if `sigma > ~200`. */ - if (sigma >= 3.556f) { - q = 0.9804f * (sigma - 3.556f) + 2.5091f; - } - else { /* `sigma >= 0.5`. */ - q = (0.0561f * sigma + 0.5784f) * sigma - 0.2568f; - } - q2 = q * q; - sc = (1.1668 + q) * (3.203729649 + (2.21566 + q) * q); - /* No gabor filtering here, so no complex multiplies, just the regular coefficients. - * all negated here, so as not to have to recalc Triggs/Sdika matrix. */ - cf[1] = q * (5.788961737 + (6.76492 + 3.0 * q) * q) / sc; - cf[2] = -q2 * (3.38246 + 3.0 * q) / sc; - /* 0 & 3 unchanged. */ - cf[3] = q2 * q / sc; - cf[0] = 1.0 - cf[1] - cf[2] - cf[3]; - - /* Triggs/Sdika border corrections, - * it seems to work, not entirely sure if it is actually totally correct, - * Besides J.M.Geusebroek's `anigauss.c` (see http://www.science.uva.nl/~mark), - * found one other implementation by Cristoph Lampert, - * but neither seem to be quite the same, result seems to be ok so far anyway. - * Extra scale factor here to not have to do it in filter, - * though maybe this had something to with the precision errors */ - sc = cf[0] / ((1.0 + cf[1] - cf[2] + cf[3]) * (1.0 - cf[1] - cf[2] - cf[3]) * - (1.0 + cf[2] + (cf[1] - cf[3]) * cf[3])); - tsM[0] = sc * (-cf[3] * cf[1] + 1.0 - cf[3] * cf[3] - cf[2]); - tsM[1] = sc * ((cf[3] + cf[1]) * (cf[2] + cf[3] * cf[1])); - tsM[2] = sc * (cf[3] * (cf[1] + cf[3] * cf[2])); - tsM[3] = sc * (cf[1] + cf[3] * cf[2]); - tsM[4] = sc * (-(cf[2] - 1.0) * (cf[2] + cf[3] * cf[1])); - tsM[5] = sc * (-(cf[3] * cf[1] + cf[3] * cf[3] + cf[2] - 1.0) * cf[3]); - tsM[6] = sc * (cf[3] * cf[1] + cf[2] + cf[1] * cf[1] - cf[2] * cf[2]); - tsM[7] = sc * (cf[1] * cf[2] + cf[3] * cf[2] * cf[2] - cf[1] * cf[3] * cf[3] - - cf[3] * cf[3] * cf[3] - cf[3] * cf[2] + cf[3]); - tsM[8] = sc * (cf[3] * (cf[1] + cf[3] * cf[2])); - -#define YVV(L) \ - { \ - W[0] = cf[0] * X[0] + cf[1] * X[0] + cf[2] * X[0] + cf[3] * X[0]; \ - W[1] = cf[0] * X[1] + cf[1] * W[0] + cf[2] * X[0] + cf[3] * X[0]; \ - W[2] = cf[0] * X[2] + cf[1] * W[1] + cf[2] * W[0] + cf[3] * X[0]; \ - for (i = 3; i < L; i++) { \ - W[i] = cf[0] * X[i] + cf[1] * W[i - 1] + cf[2] * W[i - 2] + cf[3] * W[i - 3]; \ - } \ - tsu[0] = W[L - 1] - X[L - 1]; \ - tsu[1] = W[L - 2] - X[L - 1]; \ - tsu[2] = W[L - 3] - X[L - 1]; \ - tsv[0] = tsM[0] * tsu[0] + tsM[1] * tsu[1] + tsM[2] * tsu[2] + X[L - 1]; \ - tsv[1] = tsM[3] * tsu[0] + tsM[4] * tsu[1] + tsM[5] * tsu[2] + X[L - 1]; \ - tsv[2] = tsM[6] * tsu[0] + tsM[7] * tsu[1] + tsM[8] * tsu[2] + X[L - 1]; \ - Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \ - Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \ - Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \ - /* `i != UINT_MAX` is really `i >= 0`, but necessary for `uint` wrapping. */ \ - for (i = L - 4; i != UINT_MAX; i--) { \ - Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \ - } \ - } \ - (void)0 - - /* Intermediate buffers. */ - src_dim_max = std::max(src_width, src_height); - X = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss X buf"); - Y = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss Y buf"); - W = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss W buf"); - if (xy & 1) { /* H. */ - int offset; - for (y = 0; y < src_height; y++) { - const int yx = y * src_width; - offset = yx * num_channels + chan; - for (x = 0; x < src_width; x++) { - X[x] = buffer[offset]; - offset += num_channels; - } - YVV(src_width); - offset = yx * num_channels + chan; - for (x = 0; x < src_width; x++) { - buffer[offset] = Y[x]; - offset += num_channels; - } - } - } - if (xy & 2) { /* V. */ - int offset; - const int add = src_width * num_channels; - - for (x = 0; x < src_width; x++) { - offset = x * num_channels + chan; - for (y = 0; y < src_height; y++) { - X[y] = buffer[offset]; - offset += add; - } - YVV(src_height); - offset = x * num_channels + chan; - for (y = 0; y < src_height; y++) { - buffer[offset] = Y[y]; - offset += add; - } - } - } - - MEM_freeN(X); - MEM_freeN(W); - MEM_freeN(Y); -#undef YVV -} - -void FastGaussianBlurOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: - r_input_area = this->get_canvas(); - break; - default: - BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area); - return; - } -} - -void FastGaussianBlurOperation::update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - /* TODO(manzanilla): Add a render test and make #IIR_gauss multi-threaded with support for - * an output buffer. */ - const MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX]; - MemoryBuffer *image = nullptr; - const bool is_full_output = BLI_rcti_compare(&output->get_rect(), &area); - if (is_full_output) { - image = output; - } - else { - image = new MemoryBuffer(get_output_socket()->get_data_type(), area); - } - image->copy_from(input, area); - - if ((sigma_x_ == sigma_y_) && (sigma_x_ > 0.0f)) { - for (const int c : IndexRange(COM_DATA_TYPE_COLOR_CHANNELS)) { - IIR_gauss(image, sigma_x_, c, 3); - } - } - else { - if (sigma_x_ > 0.0f) { - for (const int c : IndexRange(COM_DATA_TYPE_COLOR_CHANNELS)) { - IIR_gauss(image, sigma_x_, c, 1); - } - } - if (sigma_y_ > 0.0f) { - for (const int c : IndexRange(COM_DATA_TYPE_COLOR_CHANNELS)) { - IIR_gauss(image, sigma_y_, c, 2); - } - } - } - - if (!is_full_output) { - output->copy_from(image, area); - delete image; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h deleted file mode 100644 index ec79360001a..00000000000 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_BlurBaseOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class FastGaussianBlurOperation : public BlurBaseOperation { - private: - float sigma_x_; - float sigma_y_; - MemoryBuffer *iirgaus_; - - public: - FastGaussianBlurOperation(); - - static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy); - void init_data() override; - void deinit_execution() override; - void init_execution() override; - - void set_size(int size_x, int size_y); - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void update_memory_buffer_partial(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) override - { - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FileOutputOperation.cc b/source/blender/compositor/operations/COM_FileOutputOperation.cc deleted file mode 100644 index 7b52544a37d..00000000000 --- a/source/blender/compositor/operations/COM_FileOutputOperation.cc +++ /dev/null @@ -1,478 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "BLI_assert.h" -#include "BLI_fileops.h" -#include "BLI_index_range.hh" -#include "BLI_path_utils.hh" -#include "BLI_string.h" -#include "BLI_string_utils.hh" -#include "BLI_task.hh" -#include "BLI_utildefines.h" - -#include "DNA_node_types.h" -#include "DNA_scene_types.h" - -#include "BKE_image.hh" -#include "BKE_image_format.hh" -#include "BKE_main.hh" -#include "BKE_scene.hh" - -#include "RE_pipeline.h" - -#include "COM_FileOutputOperation.h" -#include "COM_render_context.hh" - -namespace blender::compositor { - -FileOutputInput::FileOutputInput(NodeImageMultiFileSocket *data, - DataType data_type, - DataType original_data_type) - : data(data), data_type(data_type), original_data_type(original_data_type) -{ -} - -static int get_channels_count(DataType datatype) -{ - switch (datatype) { - case DataType::Value: - return 1; - case DataType::Vector: - return 3; - case DataType::Color: - return 4; - default: - return 0; - } -} - -static float *initialize_buffer(uint width, uint height, DataType datatype) -{ - const int size = get_channels_count(datatype); - return static_cast( - MEM_malloc_arrayN(size_t(width) * height, sizeof(float) * size, "File Output Buffer.")); -} - -FileOutputOperation::FileOutputOperation(const CompositorContext *context, - const NodeImageMultiFile *node_data, - Vector inputs) - : context_(context), node_data_(node_data), file_output_inputs_(inputs) -{ - /* Inputs for multi-layer files need to be the same size, while they can be different for - * individual file outputs. */ - const ResizeMode resize_mode = this->is_multi_layer() ? ResizeMode::Center : ResizeMode::None; - - for (const FileOutputInput &input : inputs) { - add_input_socket(input.data_type, resize_mode); - } - this->set_canvas_input_index(RESOLUTION_INPUT_ANY); -} - -void FileOutputOperation::init_execution() -{ - for (int i = 0; i < file_output_inputs_.size(); i++) { - FileOutputInput &input = file_output_inputs_[i]; - input.image_input = get_input_socket_reader(i); - if (!input.image_input) { - continue; - } - input.output_buffer = initialize_buffer( - input.image_input->get_width(), input.image_input->get_height(), input.data_type); - } -} - -void FileOutputOperation::update_memory_buffer(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span inputs) -{ - for (int i = 0; i < file_output_inputs_.size(); i++) { - const FileOutputInput &input = file_output_inputs_[i]; - if (!input.output_buffer) { - continue; - } - - int channels_count = get_channels_count(input.data_type); - MemoryBuffer output_buf( - input.output_buffer, channels_count, inputs[i]->get_width(), inputs[i]->get_height()); - output_buf.copy_from(inputs[i], inputs[i]->get_rect(), 0, inputs[i]->get_num_channels(), 0); - } -} - -static void add_meta_data_for_input(realtime_compositor::FileOutput &file_output, - const FileOutputInput &input) -{ - std::unique_ptr meta_data = input.image_input->get_meta_data(); - if (!meta_data) { - return; - } - - blender::StringRef layer_name = blender::bke::cryptomatte::BKE_cryptomatte_extract_layer_name( - blender::StringRef(input.data->layer, - BLI_strnlen(input.data->layer, sizeof(input.data->layer)))); - meta_data->replace_hash_neutral_cryptomatte_keys(layer_name); - meta_data->for_each_entry([&](const std::string &key, const std::string &value) { - file_output.add_meta_data(key, value); - }); -} - -void FileOutputOperation::deinit_execution() -{ - /* It is possible that none of the inputs would have an image connected, which will materialize - * as a size of zero, so check this here and return early doing nothing. Just make sure to free - * the allocated buffers. */ - const int2 size = int2(get_width(), get_height()); - if (size == int2(0)) { - for (const FileOutputInput &input : file_output_inputs_) { - /* Ownership of outputs buffers are transferred to file outputs, so if we are not writing a - * file output, we need to free the output buffer here. */ - if (input.output_buffer) { - MEM_freeN(input.output_buffer); - } - } - return; - } - - if (is_multi_layer()) { - execute_multi_layer(); - } - else { - execute_single_layer(); - } -} - -/* -------------------- - * Single Layer Images. - */ - -void FileOutputOperation::execute_single_layer() -{ - for (const FileOutputInput &input : file_output_inputs_) { - /* We only write images, not single values. */ - if (!input.image_input || input.image_input->get_flags().is_constant_operation) { - /* Ownership of outputs buffers are transferred to file outputs, so if we are not writing a - * file output, we need to free the output buffer here. */ - if (input.output_buffer) { - MEM_freeN(input.output_buffer); - } - continue; - } - - char base_path[FILE_MAX]; - get_single_layer_image_base_path(input.data->path, base_path); - - /* The image saving code expects EXR images to have a different structure than standard - * images. In particular, in EXR images, the buffers need to be stored in passes that are, in - * turn, stored in a render layer. On the other hand, in non-EXR images, the buffers need to - * be stored in views. An exception to this is stereo images, which needs to have the same - * structure as non-EXR images. */ - const auto &format = input.data->use_node_format ? node_data_->format : input.data->format; - const bool save_as_render = input.data->use_node_format ? node_data_->save_as_render : - input.data->save_as_render; - const bool is_exr = format.imtype == R_IMF_IMTYPE_OPENEXR; - const int views_count = BKE_scene_multiview_num_views_get(context_->get_render_data()); - if (is_exr && !(format.views_format == R_IMF_VIEWS_STEREO_3D && views_count == 2)) { - execute_single_layer_multi_view_exr(input, format, base_path); - continue; - } - - char image_path[FILE_MAX]; - get_single_layer_image_path(base_path, format, image_path); - - const int2 size = int2(input.image_input->get_width(), input.image_input->get_height()); - realtime_compositor::FileOutput &file_output = context_->get_render_context()->get_file_output( - image_path, format, size, save_as_render); - - add_view_for_input(file_output, input, context_->get_view_name()); - - add_meta_data_for_input(file_output, input); - } -} - -/* ----------------------------------- - * Single Layer Multi-View EXR Images. - */ - -void FileOutputOperation::execute_single_layer_multi_view_exr(const FileOutputInput &input, - const ImageFormatData &format, - const char *base_path) -{ - const bool has_views = format.views_format != R_IMF_VIEWS_INDIVIDUAL; - - /* The EXR stores all views in the same file, so we supply an empty view to make sure the file - * name does not contain a view suffix. */ - char image_path[FILE_MAX]; - const char *path_view = has_views ? "" : context_->get_view_name(); - get_multi_layer_exr_image_path(base_path, path_view, image_path); - - const int2 size = int2(input.image_input->get_width(), input.image_input->get_height()); - realtime_compositor::FileOutput &file_output = context_->get_render_context()->get_file_output( - image_path, format, size, true); - - /* The EXR stores all views in the same file, so we add the actual render view. Otherwise, we - * add a default unnamed view. */ - const char *view_name = has_views ? context_->get_view_name() : ""; - file_output.add_view(view_name); - add_pass_for_input(file_output, input, "", view_name); - - add_meta_data_for_input(file_output, input); -} - -/* ----------------------- - * Multi-Layer EXR Images. - */ - -void FileOutputOperation::execute_multi_layer() -{ - const bool store_views_in_single_file = is_multi_view_exr(); - const char *view = context_->get_view_name(); - - /* If we are saving all views in a single multi-layer file, we supply an empty view to make - * sure the file name does not contain a view suffix. */ - char image_path[FILE_MAX]; - const char *write_view = store_views_in_single_file ? "" : view; - get_multi_layer_exr_image_path(get_base_path(), write_view, image_path); - - const int2 size = int2(get_width(), get_height()); - const ImageFormatData format = node_data_->format; - realtime_compositor::FileOutput &file_output = context_->get_render_context()->get_file_output( - image_path, format, size, true); - - /* If we are saving views in separate files, we needn't store the view in the channel names, so - * we add an unnamed view. */ - const char *pass_view = store_views_in_single_file ? view : ""; - file_output.add_view(pass_view); - - for (const FileOutputInput &input : file_output_inputs_) { - if (!input.image_input) { - /* Ownership of outputs buffers are transferred to file outputs, so if we are not writing a - * file output, we need to free the output buffer here. */ - if (input.output_buffer) { - MEM_freeN(input.output_buffer); - } - continue; - } - - const char *pass_name = input.data->layer; - add_pass_for_input(file_output, input, pass_name, pass_view); - - add_meta_data_for_input(file_output, input); - } -} - -/* Given a float4 image, return a newly allocated float3 image that ignores the last channel. The - * input image is freed. */ -static float *float4_to_float3_image(int2 size, float *float4_image) -{ - float *float3_image = static_cast( - MEM_malloc_arrayN(size_t(size.x) * size.y, sizeof(float[3]), "File Output Vector Buffer.")); - - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - for (int i = 0; i < 3; i++) { - const int pixel_index = y * size.x + x; - float3_image[pixel_index * 3 + i] = float4_image[pixel_index * 4 + i]; - } - } - } - }); - - MEM_freeN(float4_image); - return float3_image; -} - -/* Allocates and fills an image buffer of the specified size with the value of the given constant - * input. */ -static float *inflate_input(const FileOutputInput &input, const int2 size) -{ - BLI_assert(input.image_input->get_flags().is_constant_operation); - - switch (input.data_type) { - case DataType::Value: { - float *buffer = static_cast(MEM_malloc_arrayN( - size_t(size.x) * size.y, sizeof(float), "File Output Inflated Buffer.")); - - const float value = input.image_input->get_constant_value_default(0.0f); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - buffer[y * size.x + x] = value; - } - } - }); - return buffer; - } - case DataType::Color: { - float *buffer = static_cast(MEM_malloc_arrayN( - size_t(size.x) * size.y, sizeof(float[4]), "File Output Inflated Buffer.")); - - const float *value = input.image_input->get_constant_elem_default(nullptr); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - copy_v4_v4(buffer + ((y * size.x + x) * 4), value); - } - } - }); - return buffer; - } - default: - /* Vector types are not possible for File output, see get_input_data_type in - * COM_FileOutputNode.cc for more information. Other types are internal and needn't be - * handled by operations. */ - break; - } - - BLI_assert_unreachable(); - return nullptr; -} - -void FileOutputOperation::add_pass_for_input(realtime_compositor::FileOutput &file_output, - const FileOutputInput &input, - const char *pass_name, - const char *view_name) -{ - /* For constant operations, we fill a buffer that covers the canvas of the operation with the - * value of the operation. */ - const int2 size = input.image_input->get_flags().is_constant_operation ? - int2(this->get_width(), this->get_height()) : - int2(input.image_input->get_width(), input.image_input->get_height()); - - /* The image buffer in the file output will take ownership of this buffer and freeing it will be - * its responsibility. So if we don't use the output buffer, we need to free it here. */ - float *buffer = nullptr; - if (input.image_input->get_flags().is_constant_operation) { - buffer = inflate_input(input, size); - MEM_freeN(input.output_buffer); - } - else { - buffer = input.output_buffer; - } - - switch (input.original_data_type) { - case DataType::Color: - /* Use lowercase rgba for Cryptomatte layers because the EXR internal compression rules - * specify that all uppercase RGBA channels will be compressed, and Cryptomatte should not be - * compressed. */ - if (input.image_input->get_meta_data() && - input.image_input->get_meta_data()->is_cryptomatte_layer()) - { - file_output.add_pass(pass_name, view_name, "rgba", buffer); - } - else { - file_output.add_pass(pass_name, view_name, "RGBA", buffer); - } - break; - case DataType::Vector: - if (input.image_input->get_meta_data() && input.image_input->get_meta_data()->is_4d_vector) { - file_output.add_pass(pass_name, view_name, "XYZW", buffer); - } - else { - file_output.add_pass(pass_name, view_name, "XYZ", float4_to_float3_image(size, buffer)); - } - break; - case DataType::Value: - file_output.add_pass(pass_name, view_name, "V", buffer); - break; - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } -} - -void FileOutputOperation::add_view_for_input(realtime_compositor::FileOutput &file_output, - const FileOutputInput &input, - const char *view_name) -{ - const int2 size = int2(input.image_input->get_width(), input.image_input->get_height()); - switch (input.original_data_type) { - case DataType::Color: - file_output.add_view(view_name, 4, input.output_buffer); - break; - case DataType::Vector: - file_output.add_view(view_name, 3, float4_to_float3_image(size, input.output_buffer)); - break; - case DataType::Value: - file_output.add_view(view_name, 1, input.output_buffer); - break; - case DataType::Float2: - /* An internal type that needn't be handled. */ - BLI_assert_unreachable(); - break; - } -} - -void FileOutputOperation::get_single_layer_image_base_path(const char *base_name, char *base_path) -{ - if (base_name[0]) { - BLI_path_join(base_path, FILE_MAX, get_base_path(), base_name); - } - else { - BLI_strncpy(base_path, get_base_path(), FILE_MAX); - BLI_path_slash_ensure(base_path, FILE_MAX); - } -} - -void FileOutputOperation::get_single_layer_image_path(const char *base_path, - const ImageFormatData &format, - char *image_path) -{ - BKE_image_path_from_imformat(image_path, - base_path, - BKE_main_blendfile_path_from_global(), - context_->get_framenumber(), - &format, - use_file_extension(), - true, - nullptr); -} - -void FileOutputOperation::get_multi_layer_exr_image_path(const char *base_path, - const char *view, - char *image_path) -{ - const char *suffix = BKE_scene_multiview_view_suffix_get(context_->get_render_data(), view); - BKE_image_path_from_imtype(image_path, - base_path, - BKE_main_blendfile_path_from_global(), - context_->get_framenumber(), - R_IMF_IMTYPE_MULTILAYER, - use_file_extension(), - true, - suffix); -} - -bool FileOutputOperation::is_multi_layer() -{ - return node_data_->format.imtype == R_IMF_IMTYPE_MULTILAYER; -} - -const char *FileOutputOperation::get_base_path() -{ - return node_data_->base_path; -} - -bool FileOutputOperation::use_file_extension() -{ - return context_->get_render_data()->scemode & R_EXTENSION; -} - -bool FileOutputOperation::is_multi_view_exr() -{ - if (!is_multi_view_scene()) { - return false; - } - - return node_data_->format.views_format == R_IMF_VIEWS_MULTIVIEW; -} - -bool FileOutputOperation::is_multi_view_scene() -{ - return context_->get_render_data()->scemode & R_MULTIVIEW; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FileOutputOperation.h b/source/blender/compositor/operations/COM_FileOutputOperation.h deleted file mode 100644 index ad042baefcd..00000000000 --- a/source/blender/compositor/operations/COM_FileOutputOperation.h +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_vector.hh" - -#include "DNA_node_types.h" - -#include "COM_CompositorContext.h" -#include "COM_NodeOperation.h" - -namespace blender::realtime_compositor { -class FileOutput; -} - -namespace blender::compositor { - -struct FileOutputInput { - FileOutputInput(NodeImageMultiFileSocket *data, DataType data_type, DataType original_data_type); - - NodeImageMultiFileSocket *data; - /* The internal data type of the input in the operation, which can be different from the UI type. - * See the get_input_data_type function in COM_FileOutputNode.cc for more information. */ - DataType data_type; - /* Stores the original data type of socket in the UI, see data_type above for more information - * about the distinction. */ - DataType original_data_type; - - float *output_buffer = nullptr; - SocketReader *image_input = nullptr; -}; - -class FileOutputOperation : public NodeOperation { - private: - const CompositorContext *context_; - const NodeImageMultiFile *node_data_; - Vector file_output_inputs_; - - public: - FileOutputOperation(const CompositorContext *context, - const NodeImageMultiFile *node_data, - Vector inputs); - - bool is_output_operation(bool /*rendering*/) const override - { - return true; - } - void init_execution() override; - void deinit_execution() override; - eCompositorPriority get_render_priority() const override - { - return eCompositorPriority::Low; - } - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - void execute_single_layer(); - void execute_single_layer_multi_view_exr(const FileOutputInput &input, - const ImageFormatData &format, - const char *base_path); - void execute_multi_layer(); - - /* Add a pass of the given name, view, and input buffer. The pass channel identifiers follows the - * EXR conventions. */ - void add_pass_for_input(realtime_compositor::FileOutput &file_output, - const FileOutputInput &input, - const char *pass_name, - const char *view_name); - - /* Add a view of the given name and input buffer. */ - void add_view_for_input(realtime_compositor::FileOutput &file_output, - const FileOutputInput &input, - const char *view_name); - - /* Get the base path of the image to be saved, based on the base path of the node. The base name - * is an optional initial name of the image, which will later be concatenated with other - * information like the frame number, view, and extension. If the base name is empty, then the - * base path represents a directory, so a trailing slash is ensured. */ - void get_single_layer_image_base_path(const char *base_name, char *base_path); - - /* Get the path of the image to be saved based on the given format. */ - void get_single_layer_image_path(const char *base_path, - const ImageFormatData &format, - char *image_path); - - /* Get the path of the EXR image to be saved. If the given view is not empty, its corresponding - * file suffix will be appended to the name. */ - void get_multi_layer_exr_image_path(const char *base_path, const char *view, char *image_path); - - bool is_multi_layer(); - - const char *get_base_path(); - - /* Add the file format extensions to the rendered file name. */ - bool use_file_extension(); - - /* If true, save views in a multi-view EXR file, otherwise, save each view in its own file. */ - bool is_multi_view_exr(); - - bool is_multi_view_scene(); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FlipOperation.cc b/source/blender/compositor/operations/COM_FlipOperation.cc deleted file mode 100644 index 04bf25baa6e..00000000000 --- a/source/blender/compositor/operations/COM_FlipOperation.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_FlipOperation.h" - -namespace blender::compositor { - -FlipOperation::FlipOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::None); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - flip_x_ = true; - flip_y_ = false; - flags_.can_be_constant = true; -} - -void FlipOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - - /* The full input image should be flipped to avoid cropping effects caused by previous scaling or - * translating, or a smaller output area. */ - r_input_area = get_canvas(); -} - -void FlipOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[0]; - if (input_img->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input_img->get_elem(0, 0)); - return; - } - const int input_offset_x = input_img->get_rect().xmin; - const int input_offset_y = input_img->get_rect().ymin; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - const int nx = flip_x_ ? (int(this->get_width()) - 1) - it.x : it.x; - const int ny = flip_y_ ? (int(this->get_height()) - 1) - it.y : it.y; - input_img->read_elem(input_offset_x + nx, input_offset_y + ny, it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h deleted file mode 100644 index 0abb346c02c..00000000000 --- a/source/blender/compositor/operations/COM_FlipOperation.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class FlipOperation : public MultiThreadedOperation { - private: - bool flip_x_; - bool flip_y_; - - public: - FlipOperation(); - - void setFlipX(bool flipX) - { - flip_x_ = flipX; - } - void setFlipY(bool flipY) - { - flip_y_ = flipY; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cc b/source/blender/compositor/operations/COM_GammaCorrectOperation.cc deleted file mode 100644 index a7f5163486d..00000000000 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GammaCorrectOperation.h" - -namespace blender::compositor { - -GammaCorrectOperation::GammaCorrectOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void GammaCorrectOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float color[4]; - input->read_elem(it.x, it.y, color); - if (color[3] > 0.0f) { - color[0] /= color[3]; - color[1] /= color[3]; - color[2] /= color[3]; - } - - /* Check for negative to avoid NAN's. */ - it.out[0] = color[0] > 0.0f ? color[0] * color[0] : 0.0f; - it.out[1] = color[1] > 0.0f ? color[1] * color[1] : 0.0f; - it.out[2] = color[2] > 0.0f ? color[2] * color[2] : 0.0f; - it.out[3] = color[3]; - - if (color[3] > 0.0f) { - it.out[0] *= color[3]; - it.out[1] *= color[3]; - it.out[2] *= color[3]; - } - } -} - -GammaUncorrectOperation::GammaUncorrectOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void GammaUncorrectOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float color[4]; - input->read_elem(it.x, it.y, color); - if (color[3] > 0.0f) { - color[0] /= color[3]; - color[1] /= color[3]; - color[2] /= color[3]; - } - - it.out[0] = color[0] > 0.0f ? sqrtf(color[0]) : 0.0f; - it.out[1] = color[1] > 0.0f ? sqrtf(color[1]) : 0.0f; - it.out[2] = color[2] > 0.0f ? sqrtf(color[2]) : 0.0f; - it.out[3] = color[3]; - - if (color[3] > 0.0f) { - it.out[0] *= color[3]; - it.out[1] *= color[3]; - it.out[2] *= color[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h deleted file mode 100644 index ed5b889670e..00000000000 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class GammaCorrectOperation : public MultiThreadedOperation { - public: - GammaCorrectOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class GammaUncorrectOperation : public MultiThreadedOperation { - public: - GammaUncorrectOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GammaOperation.cc b/source/blender/compositor/operations/COM_GammaOperation.cc deleted file mode 100644 index 27928285bc8..00000000000 --- a/source/blender/compositor/operations/COM_GammaOperation.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GammaOperation.h" - -namespace blender::compositor { - -GammaOperation::GammaOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void GammaOperation::update_memory_buffer_row(PixelCursor &p) -{ - for (; p.out < p.row_end; p.next()) { - const float *in_value = p.ins[0]; - const float *in_gamma = p.ins[1]; - const float gamma = in_gamma[0]; - /* Check for negative to avoid NAN's. */ - p.out[0] = in_value[0] > 0.0f ? powf(in_value[0], gamma) : in_value[0]; - p.out[1] = in_value[1] > 0.0f ? powf(in_value[1], gamma) : in_value[1]; - p.out[2] = in_value[2] > 0.0f ? powf(in_value[2], gamma) : in_value[2]; - p.out[3] = in_value[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h deleted file mode 100644 index 728060faf83..00000000000 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedRowOperation.h" - -namespace blender::compositor { - -class GammaOperation : public MultiThreadedRowOperation { - public: - GammaOperation(); - - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc deleted file mode 100644 index dab15bd8915..00000000000 --- a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc +++ /dev/null @@ -1,144 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GaussianAlphaBlurBaseOperation.h" - -namespace blender::compositor { - -GaussianAlphaBlurBaseOperation::GaussianAlphaBlurBaseOperation(eDimension dim) - : BlurBaseOperation(DataType::Value) -{ - gausstab_ = nullptr; - filtersize_ = 0; - falloff_ = -1; /* Intentionally invalid, so we can detect uninitialized values. */ - dimension_ = dim; -} - -void GaussianAlphaBlurBaseOperation::init_data() -{ - BlurBaseOperation::init_data(); - rad_ = max_ff(size_ * this->get_blur_size(dimension_), 0.0f); - rad_ = min_ff(rad_, MAX_GAUSSTAB_RADIUS); - filtersize_ = min_ii(ceil(rad_), MAX_GAUSSTAB_RADIUS); -} - -void GaussianAlphaBlurBaseOperation::init_execution() -{ - BlurBaseOperation::init_execution(); - gausstab_ = BlurBaseOperation::make_gausstab(rad_, filtersize_); - distbuf_inv_ = BlurBaseOperation::make_dist_fac_inverse(rad_, filtersize_, falloff_); -} - -void GaussianAlphaBlurBaseOperation::deinit_execution() -{ - BlurBaseOperation::deinit_execution(); - - if (gausstab_) { - MEM_freeN(gausstab_); - gausstab_ = nullptr; - } - - if (distbuf_inv_) { - MEM_freeN(distbuf_inv_); - distbuf_inv_ = nullptr; - } -} - -void GaussianAlphaBlurBaseOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx != IMAGE_INPUT_INDEX) { - BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area); - return; - } - - r_input_area = output_area; - switch (dimension_) { - case eDimension::X: - r_input_area.xmin = output_area.xmin - filtersize_ - 1; - r_input_area.xmax = output_area.xmax + filtersize_ + 1; - break; - case eDimension::Y: - r_input_area.ymin = output_area.ymin - filtersize_ - 1; - r_input_area.ymax = output_area.ymax + filtersize_ + 1; - break; - } -} - -void GaussianAlphaBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX]; - const rcti &input_rect = input->get_rect(); - BuffersIterator it = output->iterate_with({input}, area); - - int min_input_coord = -1; - int max_input_coord = -1; - int elem_stride = -1; - std::function get_current_coord; - switch (dimension_) { - case eDimension::X: - min_input_coord = input_rect.xmin; - max_input_coord = input_rect.xmax; - get_current_coord = [&] { return it.x; }; - elem_stride = input->elem_stride; - break; - case eDimension::Y: - min_input_coord = input_rect.ymin; - max_input_coord = input_rect.ymax; - get_current_coord = [&] { return it.y; }; - elem_stride = input->row_stride; - break; - } - - for (; !it.is_end(); ++it) { - const int coord = get_current_coord(); - const int coord_min = max_ii(coord - filtersize_, min_input_coord); - const int coord_max = min_ii(coord + filtersize_ + 1, max_input_coord); - - /* *** This is the main part which is different to #GaussianBlurBaseOperation. *** */ - /* Gauss. */ - float alpha_accum = 0.0f; - float multiplier_accum = 0.0f; - - /* Dilate. */ - const bool do_invert = do_subtract_; - /* Init with the current color to avoid unneeded lookups. */ - float value_max = finv_test(*it.in(0), do_invert); - float distfacinv_max = 1.0f; /* 0 to 1 */ - - const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride; - const int in_stride = elem_stride; - int index = (coord_min - coord) + filtersize_; - const int index_end = index + (coord_max - coord_min); - for (; index < index_end; in += in_stride, ++index) { - float value = finv_test(*in, do_invert); - - /* Gauss. */ - float multiplier = gausstab_[index]; - alpha_accum += value * multiplier; - multiplier_accum += multiplier; - - /* Dilate - find most extreme color. */ - if (value > value_max) { - multiplier = distbuf_inv_[index]; - value *= multiplier; - if (value > value_max) { - value_max = value; - distfacinv_max = multiplier; - } - } - } - - /* Blend between the max value and gauss blue - gives nice feather. */ - const float value_blur = alpha_accum / multiplier_accum; - const float value_final = (value_max * distfacinv_max) + - (value_blur * (1.0f - distfacinv_max)); - *it.out = finv_test(value_final, do_invert); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.h deleted file mode 100644 index b0ed3608fb1..00000000000 --- a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_BlurBaseOperation.h" - -namespace blender::compositor { - -class GaussianAlphaBlurBaseOperation : public BlurBaseOperation { - protected: - float *gausstab_; - float *distbuf_inv_; - int falloff_; /* Falloff for #distbuf_inv. */ - bool do_subtract_; - int filtersize_; - float rad_; - eDimension dimension_; - - public: - GaussianAlphaBlurBaseOperation(eDimension dim); - - virtual void init_data() override; - virtual void init_execution() override; - virtual void deinit_execution() override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) final; - - /** - * Set subtract for Dilate/Erode functionality - */ - void set_subtract(bool subtract) - { - do_subtract_ = subtract; - } - void set_falloff(int falloff) - { - falloff_ = falloff; - } - - BLI_INLINE float finv_test(const float f, const bool test) - { - return (LIKELY(test == false)) ? f : 1.0f - f; - } -}; - -class GaussianAlphaXBlurOperation : public GaussianAlphaBlurBaseOperation { - public: - GaussianAlphaXBlurOperation() : GaussianAlphaBlurBaseOperation(eDimension::X) {} -}; - -class GaussianAlphaYBlurOperation : public GaussianAlphaBlurBaseOperation { - public: - GaussianAlphaYBlurOperation() : GaussianAlphaBlurBaseOperation(eDimension::Y) {} -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc deleted file mode 100644 index ac2ff5407ea..00000000000 --- a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GaussianBlurBaseOperation.h" - -namespace blender::compositor { - -GaussianBlurBaseOperation::GaussianBlurBaseOperation(eDimension dim) - : BlurBaseOperation(DataType::Color) -{ - gausstab_ = nullptr; -#if BLI_HAVE_SSE2 - gausstab_sse_ = nullptr; -#endif - filtersize_ = 0; - rad_ = 0.0f; - dimension_ = dim; -} - -void GaussianBlurBaseOperation::init_data() -{ - BlurBaseOperation::init_data(); - rad_ = max_ff(size_ * this->get_blur_size(dimension_), 0.0f); - rad_ = min_ff(rad_, MAX_GAUSSTAB_RADIUS); - filtersize_ = min_ii(ceil(rad_), MAX_GAUSSTAB_RADIUS); -} - -void GaussianBlurBaseOperation::init_execution() -{ - BlurBaseOperation::init_execution(); - gausstab_ = BlurBaseOperation::make_gausstab(rad_, filtersize_); -#if BLI_HAVE_SSE2 - gausstab_sse_ = BlurBaseOperation::convert_gausstab_sse(gausstab_, filtersize_); -#endif -} - -void GaussianBlurBaseOperation::deinit_execution() -{ - BlurBaseOperation::deinit_execution(); - - if (gausstab_) { - MEM_freeN(gausstab_); - gausstab_ = nullptr; - } -#if BLI_HAVE_SSE2 - if (gausstab_sse_) { - MEM_freeN(gausstab_sse_); - gausstab_sse_ = nullptr; - } -#endif -} - -void GaussianBlurBaseOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx != IMAGE_INPUT_INDEX) { - BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area); - return; - } - - r_input_area = output_area; - switch (dimension_) { - case eDimension::X: - r_input_area.xmin = output_area.xmin - filtersize_ - 1; - r_input_area.xmax = output_area.xmax + filtersize_ + 1; - break; - case eDimension::Y: - r_input_area.ymin = output_area.ymin - filtersize_ - 1; - r_input_area.ymax = output_area.ymax + filtersize_ + 1; - break; - } -} - -void GaussianBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const int2 unit_offset = dimension_ == eDimension::X ? int2(1, 0) : int2(0, 1); - MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX]; - for (BuffersIterator it = output->iterate_with({input}, area); !it.is_end(); ++it) { - alignas(16) float4 accumulated_color = float4(0.0f); -#if BLI_HAVE_SSE2 - __m128 accumulated_color_sse = _mm_setzero_ps(); - for (int i = -filtersize_; i <= filtersize_; i++) { - const int2 offset = unit_offset * i; - __m128 weight = gausstab_sse_[i + filtersize_]; - __m128 color = _mm_load_ps(input->get_elem_clamped(it.x + offset.x, it.y + offset.y)); - __m128 weighted_color = _mm_mul_ps(color, weight); - accumulated_color_sse = _mm_add_ps(accumulated_color_sse, weighted_color); - } - _mm_store_ps(accumulated_color, accumulated_color_sse); -#else - for (int i = -filtersize_; i <= filtersize_; i++) { - const int2 offset = unit_offset * i; - const float weight = gausstab_[i + filtersize_]; - const float4 color = input->get_elem_clamped(it.x + offset.x, it.y + offset.y); - accumulated_color += color * weight; - } -#endif - copy_v4_v4(it.out, accumulated_color); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.h b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.h deleted file mode 100644 index c35fe56e199..00000000000 --- a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_BlurBaseOperation.h" - -namespace blender::compositor { - -class GaussianBlurBaseOperation : public BlurBaseOperation { - protected: - float *gausstab_; -#if BLI_HAVE_SSE2 - __m128 *gausstab_sse_; -#endif - int filtersize_; - float rad_; - eDimension dimension_; - - public: - GaussianBlurBaseOperation(eDimension dim); - - virtual void init_data() override; - virtual void init_execution() override; - virtual void deinit_execution() override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class GaussianXBlurOperation : public GaussianBlurBaseOperation { - public: - GaussianXBlurOperation() : GaussianBlurBaseOperation(eDimension::X) {} -}; - -class GaussianYBlurOperation : public GaussianBlurBaseOperation { - public: - GaussianYBlurOperation() : GaussianBlurBaseOperation(eDimension::Y) {} -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc deleted file mode 100644 index 2a5025ea3da..00000000000 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc +++ /dev/null @@ -1,328 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -#include "BLI_index_range.hh" -#include "BLI_math_vector.hh" - -#include "COM_GaussianBokehBlurOperation.h" - -#include "RE_pipeline.h" - -namespace blender::compositor { - -GaussianBokehBlurOperation::GaussianBokehBlurOperation() : BlurBaseOperation(DataType::Color) -{ - gausstab_ = nullptr; -} - -void GaussianBokehBlurOperation::init_data() -{ - BlurBaseOperation::init_data(); - const float width = this->get_width(); - const float height = this->get_height(); - - if (!sizeavailable_) { - update_size(); - } - - radxf_ = size_ * float(data_.sizex); - CLAMP(radxf_, 0.0f, width / 2.0f); - - /* Vertical. */ - radyf_ = size_ * float(data_.sizey); - CLAMP(radyf_, 0.0f, height / 2.0f); - - radx_ = ceil(radxf_); - rady_ = ceil(radyf_); -} - -void GaussianBokehBlurOperation::init_execution() -{ - BlurBaseOperation::init_execution(); - - if (sizeavailable_) { - update_gauss(); - } -} - -void GaussianBokehBlurOperation::update_gauss() -{ - if (gausstab_ == nullptr) { - int ddwidth = 2 * radx_ + 1; - int ddheight = 2 * rady_ + 1; - int n = ddwidth * ddheight; - /* create a full filter image */ - float *ddgauss = (float *)MEM_mallocN(sizeof(float) * n, __func__); - float *dgauss = ddgauss; - float sum = 0.0f; - float facx = (radxf_ > 0.0f ? 1.0f / radxf_ : 0.0f); - float facy = (radyf_ > 0.0f ? 1.0f / radyf_ : 0.0f); - for (int j = -rady_; j <= rady_; j++) { - for (int i = -radx_; i <= radx_; i++, dgauss++) { - float fj = float(j) * facy; - float fi = float(i) * facx; - float dist = sqrt(fj * fj + fi * fi); - *dgauss = RE_filter_value(data_.filtertype, dist); - - sum += *dgauss; - } - } - - if (sum > 0.0f) { - /* normalize */ - float norm = 1.0f / sum; - for (int j = n - 1; j >= 0; j--) { - ddgauss[j] *= norm; - } - } - else { - int center = rady_ * ddwidth + radx_; - ddgauss[center] = 1.0f; - } - - gausstab_ = ddgauss; - } -} - -void GaussianBokehBlurOperation::deinit_execution() -{ - BlurBaseOperation::deinit_execution(); - - if (gausstab_) { - MEM_freeN(gausstab_); - gausstab_ = nullptr; - } -} - -void GaussianBokehBlurOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx != IMAGE_INPUT_INDEX) { - BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area); - return; - } - - r_input_area.xmax = output_area.xmax + radx_; - r_input_area.xmin = output_area.xmin - radx_; - r_input_area.ymax = output_area.ymax + rady_; - r_input_area.ymin = output_area.ymin - rady_; -} - -void GaussianBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX]; - BuffersIterator it = output->iterate_with({}, area); - const rcti &input_rect = input->get_rect(); - for (; !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - - const int ymin = max_ii(y - rady_, input_rect.ymin); - const int ymax = min_ii(y + rady_ + 1, input_rect.ymax); - const int xmin = max_ii(x - radx_, input_rect.xmin); - const int xmax = min_ii(x + radx_ + 1, input_rect.xmax); - - float temp_color[4] = {0}; - float multiplier_accum = 0; - const int elem_step = input->elem_stride; - const int add_const = (xmin - x + radx_); - const int mul_const = (radx_ * 2 + 1); - for (int ny = ymin; ny < ymax; ++ny) { - const float *color = input->get_elem(xmin, ny); - int gauss_index = ((ny - y) + rady_) * mul_const + add_const; - const int gauss_end = gauss_index + (xmax - xmin); - for (; gauss_index < gauss_end; gauss_index += 1, color += elem_step) { - const float multiplier = gausstab_[gauss_index]; - madd_v4_v4fl(temp_color, color, multiplier); - multiplier_accum += multiplier; - } - } - - mul_v4_v4fl(it.out, temp_color, 1.0f / multiplier_accum); - } -} - -// reference image -GaussianBlurReferenceOperation::GaussianBlurReferenceOperation() - : BlurBaseOperation(DataType::Color) -{ - weights_ = nullptr; - use_variable_size_ = true; -} - -void GaussianBlurReferenceOperation::init_data() -{ - /* Setup variables for gausstab and area of interest. */ - data_.image_in_width = this->get_width(); - data_.image_in_height = this->get_height(); - if (data_.relative) { - switch (data_.aspect) { - case CMP_NODE_BLUR_ASPECT_NONE: - data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width); - data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height); - break; - case CMP_NODE_BLUR_ASPECT_Y: - data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width); - data_.sizey = int(data_.percenty * 0.01f * data_.image_in_width); - break; - case CMP_NODE_BLUR_ASPECT_X: - data_.sizex = int(data_.percentx * 0.01f * data_.image_in_height); - data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height); - break; - } - } - - /* Horizontal. */ - filtersizex_ = float(data_.sizex); - int imgx = get_width() / 2; - if (filtersizex_ > imgx) { - filtersizex_ = imgx; - } - else if (filtersizex_ < 1) { - filtersizex_ = 1; - } - radx_ = float(filtersizex_); - - /* Vertical. */ - filtersizey_ = float(data_.sizey); - int imgy = get_height() / 2; - if (filtersizey_ > imgy) { - filtersizey_ = imgy; - } - else if (filtersizey_ < 1) { - filtersizey_ = 1; - } - rady_ = float(filtersizey_); -} - -void GaussianBlurReferenceOperation::init_execution() -{ - BlurBaseOperation::init_execution(); - - update_gauss(); -} - -void GaussianBlurReferenceOperation::update_gauss() -{ - const int2 radius = int2(filtersizex_, filtersizey_); - const float2 scale = math::safe_divide(float2(1.0f), float2(radius)); - const int2 size = radius + int2(1); - - rcti weights_area; - BLI_rcti_init(&weights_area, 0, size.x, 0, size.y); - weights_ = std::make_unique(DataType::Value, weights_area, false); - - float sum = 0.0f; - - const float center_weight = RE_filter_value(data_.filtertype, 0.0f); - *weights_->get_elem(0, 0) = center_weight; - sum += center_weight; - - for (const int x : IndexRange(size.x).drop_front(1)) { - const float weight = RE_filter_value(data_.filtertype, x * scale.x); - *weights_->get_elem(x, 0) = weight; - sum += weight * 2.0f; - } - - for (const int y : IndexRange(size.y).drop_front(1)) { - const float weight = RE_filter_value(data_.filtertype, y * scale.y); - *weights_->get_elem(0, y) = weight; - sum += weight * 2.0f; - } - - for (const int y : IndexRange(size.y).drop_front(1)) { - for (const int x : IndexRange(size.x).drop_front(1)) { - const float weight = RE_filter_value(data_.filtertype, math::length(float2(x, y) * scale)); - *weights_->get_elem(x, y) = weight; - sum += weight * 4.0f; - } - } - - for (const int y : IndexRange(size.y)) { - for (const int x : IndexRange(size.x)) { - *weights_->get_elem(x, y) /= sum; - } - } -} - -void GaussianBlurReferenceOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx != IMAGE_INPUT_INDEX) { - BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area); - return; - } - - const int add_x = data_.sizex + 2; - const int add_y = data_.sizey + 2; - r_input_area.xmax = output_area.xmax + add_x; - r_input_area.xmin = output_area.xmin - add_x; - r_input_area.ymax = output_area.ymax + add_y; - r_input_area.ymin = output_area.ymin - add_y; -} - -void GaussianBlurReferenceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *size_input = inputs[SIZE_INPUT_INDEX]; - const MemoryBuffer *image_input = inputs[IMAGE_INPUT_INDEX]; - - int2 weights_size = int2(weights_->get_width(), weights_->get_height()); - int2 base_radius = weights_size - int2(1); - - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float4 accumulated_color = float4(0.0f); - float4 accumulated_weight = float4(0.0f); - - int2 radius = int2(math::ceil(float2(base_radius) * *size_input->get_elem(it.x, it.y))); - - float4 center_color = float4(image_input->get_elem_clamped(it.x, it.y)); - float center_weight = *weights_->get_elem(0, 0); - accumulated_color += center_color * center_weight; - accumulated_weight += center_weight; - - for (int x = 1; x <= radius.x; x++) { - float weight_coordinates = (x / float(radius.x)) * base_radius.x; - float weight; - weights_->read_elem_bilinear(weight_coordinates, 0.0f, &weight); - accumulated_color += float4(image_input->get_elem_clamped(it.x + x, it.y)) * weight; - accumulated_color += float4(image_input->get_elem_clamped(it.x - x, it.y)) * weight; - accumulated_weight += weight * 2.0f; - } - - for (int y = 1; y <= radius.y; y++) { - float weight_coordinates = (y / float(radius.y)) * base_radius.y; - float weight; - weights_->read_elem_bilinear(0.0f, weight_coordinates, &weight); - accumulated_color += float4(image_input->get_elem_clamped(it.x, it.y + y)) * weight; - accumulated_color += float4(image_input->get_elem_clamped(it.x, it.y - y)) * weight; - accumulated_weight += weight * 2.0f; - } - - for (int y = 1; y <= radius.y; y++) { - for (int x = 1; x <= radius.x; x++) { - float2 weight_coordinates = (float2(x, y) / float2(radius)) * float2(base_radius); - float weight; - weights_->read_elem_bilinear(weight_coordinates.x, weight_coordinates.y, &weight); - accumulated_color += float4(image_input->get_elem_clamped(it.x + x, it.y + y)) * weight; - accumulated_color += float4(image_input->get_elem_clamped(it.x - x, it.y + y)) * weight; - accumulated_color += float4(image_input->get_elem_clamped(it.x + x, it.y - y)) * weight; - accumulated_color += float4(image_input->get_elem_clamped(it.x - x, it.y - y)) * weight; - accumulated_weight += weight * 4.0f; - } - } - - accumulated_color = math::safe_divide(accumulated_color, accumulated_weight); - copy_v4_v4(it.out, accumulated_color); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h deleted file mode 100644 index 6d6c3367d59..00000000000 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_BlurBaseOperation.h" -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -class GaussianBokehBlurOperation : public BlurBaseOperation { - private: - float *gausstab_; - int radx_, rady_; - float radxf_; - float radyf_; - void update_gauss(); - - public: - GaussianBokehBlurOperation(); - void init_data() override; - void init_execution() override; - void deinit_execution() override; - - 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 inputs) override; -}; - -class GaussianBlurReferenceOperation : public BlurBaseOperation { - private: - std::unique_ptr weights_; - - void update_gauss(); - int filtersizex_; - int filtersizey_; - float radx_; - float rady_; - - public: - GaussianBlurReferenceOperation(); - void init_data() override; - void init_execution() override; - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cc b/source/blender/compositor/operations/COM_GlareBaseOperation.cc deleted file mode 100644 index 1f49351d27a..00000000000 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GlareBaseOperation.h" - -namespace blender::compositor { - -GlareBaseOperation::GlareBaseOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - settings_ = nullptr; - flags_.can_be_constant = true; - is_output_rendered_ = false; -} - -void GlareBaseOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = 0; - r_input_area.xmax = this->get_width(); - r_input_area.ymin = 0; - r_input_area.ymax = this->get_height(); -} - -void GlareBaseOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - if (!is_output_rendered_) { - MemoryBuffer *input = inputs[0]; - if (input->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input->get_elem(0, 0)); - is_output_rendered_ = true; - return; - } - - this->generate_glare(output->get_buffer(), input, settings_); - is_output_rendered_ = true; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h deleted file mode 100644 index fb9bed305ca..00000000000 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/* Utility functions used by glare, tone-map and lens distortion. */ -/* Some macros for color handling. */ -typedef float fRGB[4]; - -/* TODO: replace with BLI_math_vector. */ -/* multiply c2 by color rgb, rgb as separate arguments */ -#define fRGB_rgbmult(c, r, g, b) \ - { \ - c[0] *= (r); \ - c[1] *= (g); \ - c[2] *= (b); \ - } \ - (void)0 - -class GlareBaseOperation : public NodeOperation { - private: - /** - * \brief settings of the glare node. - */ - const NodeGlare *settings_; - - bool is_output_rendered_; - - public: - void set_glare_settings(const NodeGlare *settings) - { - settings_ = settings; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final; - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) final; - - protected: - GlareBaseOperation(); - - virtual void generate_glare(float *data, - MemoryBuffer *input_tile, - const NodeGlare *settings) = 0; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareBloomOperation.cc b/source/blender/compositor/operations/COM_GlareBloomOperation.cc deleted file mode 100644 index ad72a65fbd7..00000000000 --- a/source/blender/compositor/operations/COM_GlareBloomOperation.cc +++ /dev/null @@ -1,326 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#include "BLI_array.hh" -#include "BLI_index_range.hh" -#include "BLI_math_base.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_task.hh" - -#include "COM_GlareBloomOperation.h" - -#define MAX_GLARE_SIZE 9 - -namespace blender::compositor { - -static void upsample(const MemoryBuffer &input, MemoryBuffer &output) -{ - const int2 output_size = int2(output.get_width(), output.get_height()); - - /* All the offsets in the following code section are in the normalized pixel space of the output - * image, so compute its normalized pixel size. */ - float2 pixel_size = 1.0f / float2(output_size); - - threading::parallel_for(IndexRange(output_size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(output_size.x)) { - /* Each invocation corresponds to one output pixel, where the output has twice the size of - * the input. */ - int2 texel = int2(x, y); - - /* Add 0.5 to evaluate the buffer at the center of the pixel and divide by the image size - * to get the coordinates into the buffer's expected [0, 1] range. */ - float2 coordinates = (float2(texel) + float2(0.5)) / float2(output_size); - - /* Upsample by applying a 3x3 tent filter on the bi-linearly interpolated values evaluated - * at the center of neighboring output pixels. As more tent filter upsampling passes are - * applied, the result approximates a large sized Gaussian filter. This upsampling strategy - * is described in the talk: - * - * Next Generation Post Processing in Call of Duty: Advanced Warfare - * https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare - * - * In particular, the upsampling strategy is described and illustrated in slide 162 titled - * "Upsampling - Our Solution". */ - float4 upsampled = float4(0.0f); - upsampled += (4.0f / 16.0f) * input.texture_bilinear_extend(coordinates); - upsampled += (2.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(-1.0f, 0.0f)); - upsampled += (2.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(0.0f, 1.0f)); - upsampled += (2.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(1.0f, 0.0f)); - upsampled += (2.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(0.0f, -1.0f)); - upsampled += (1.0f / 16.0f) * input.texture_bilinear_extend( - coordinates + pixel_size * float2(-1.0f, -1.0f)); - upsampled += (1.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(-1.0f, 1.0f)); - upsampled += (1.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(1.0f, -1.0f)); - upsampled += (1.0f / 16.0f) * - input.texture_bilinear_extend(coordinates + pixel_size * float2(1.0f, 1.0f)); - - const float4 original_value = output.get_elem(texel.x, texel.y); - copy_v4_v4(output.get_elem(texel.x, texel.y), original_value + upsampled); - } - } - }); -} - -/* Computes the weighted average of the given four colors, which are assumed to the colors of - * spatially neighboring pixels. The weights are computed so as to reduce the contributions of - * fireflies on the result by applying a form of local tone mapping as described by Brian Karis in - * the article "Graphic Rants: Tone Mapping". - * - * https://graphicrants.blogspot.com/2013/12/tone-mapping.html */ -static float4 karis_brightness_weighted_sum(float4 color1, - float4 color2, - float4 color3, - float4 color4) -{ - const float4 brightness = float4(math::reduce_max(color1.xyz()), - math::reduce_max(color2.xyz()), - math::reduce_max(color3.xyz()), - math::reduce_max(color4.xyz())); - const float4 weights = 1.0f / (brightness + 1.0); - const float weights_sum = math::reduce_add(weights); - const float4 sum = color1 * weights[0] + color2 * weights[1] + color3 * weights[2] + - color4 * weights[3]; - return math::safe_divide(sum, weights_sum); -} - -static void downsample(const MemoryBuffer &input, MemoryBuffer &output, bool use_karis_average) -{ - const int2 input_size = int2(input.get_width(), input.get_height()); - const int2 output_size = int2(output.get_width(), output.get_height()); - - /* All the offsets in the following code section are in the normalized pixel space of the - * input.texture_bilinear_extend, so compute its normalized pixel size. */ - float2 pixel_size = 1.0f / float2(input_size); - - threading::parallel_for(IndexRange(output_size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(output_size.x)) { - /* Each invocation corresponds to one output pixel, where the output has half the size of - * the input. */ - int2 texel = int2(x, y); - - /* Add 0.5 to evaluate the buffer at the center of the pixel and divide by the image size - * to get the coordinates into the buffer's expected [0, 1] range. */ - float2 coordinates = (float2(texel) + float2(0.5f)) / float2(output_size); - - /* Each invocation downsamples a 6x6 area of pixels around the center of the corresponding - * output pixel, but instead of sampling each of the 36 pixels in the area, we only sample - * 13 positions using bilinear fetches at the center of a number of overlapping square - * 4-pixel groups. This downsampling strategy is described in the talk: - * - * Next Generation Post Processing in Call of Duty: Advanced Warfare - * https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare - * - * In particular, the downsampling strategy is described and illustrated in slide 153 - * titled "Downsampling - Our Solution". This is employed as it significantly improves the - * stability of the glare as can be seen in the videos in the talk. */ - float4 center = input.texture_bilinear_extend(coordinates); - float4 upper_left_near = input.texture_bilinear_extend(coordinates + - pixel_size * float2(-1.0f, 1.0f)); - float4 upper_right_near = input.texture_bilinear_extend(coordinates + - pixel_size * float2(1.0f, 1.0f)); - float4 lower_left_near = input.texture_bilinear_extend(coordinates + - pixel_size * float2(-1.0f, -1.0f)); - float4 lower_right_near = input.texture_bilinear_extend(coordinates + - pixel_size * float2(1.0f, -1.0f)); - float4 left_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(-2.0f, 0.0f)); - float4 right_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(2.0f, 0.0f)); - float4 upper_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(0.0f, 2.0f)); - float4 lower_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(0.0f, -2.0f)); - float4 upper_left_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(-2.0f, 2.0f)); - float4 upper_right_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(2.0f, 2.0f)); - float4 lower_left_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(-2.0f, -2.0f)); - float4 lower_right_far = input.texture_bilinear_extend(coordinates + - pixel_size * float2(2.0f, -2.0f)); - - if (!use_karis_average) { - /* The original weights equation mentioned in slide 153 is: - * 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1 - * The 0.5 corresponds to the center group of pixels and the 0.125 corresponds to the - * other groups of pixels. The center is sampled 4 times, the far non corner pixels are - * sampled 2 times, the near corner pixels are sampled only once; but their weight is - * quadruple the weights of other groups; so they count as sampled 4 times, finally the - * far corner pixels are sampled only once, essentially totaling 32 samples. So the - * weights are as used in the following code section. */ - float4 result = (4.0f / 32.0f) * center + - (4.0f / 32.0f) * (upper_left_near + upper_right_near + lower_left_near + - lower_right_near) + - (2.0f / 32.0f) * (left_far + right_far + upper_far + lower_far) + - (1.0f / 32.0f) * (upper_left_far + upper_right_far + lower_left_far + - lower_right_far); - copy_v4_v4(output.get_elem(texel.x, texel.y), result); - } - else { - /* Reduce the contributions of fireflies on the result by reducing each group of pixels - * using a Karis brightness weighted sum. This is described in slide 168 titled - * "Fireflies - Partial Karis Average". - * - * This needn't be done on all downsampling passes, but only the first one, since - * fireflies will not survive the first pass, later passes can use the weighted average. - */ - float4 center_weighted_sum = karis_brightness_weighted_sum( - upper_left_near, upper_right_near, lower_right_near, lower_left_near); - float4 upper_left_weighted_sum = karis_brightness_weighted_sum( - upper_left_far, upper_far, center, left_far); - float4 upper_right_weighted_sum = karis_brightness_weighted_sum( - upper_far, upper_right_far, right_far, center); - float4 lower_right_weighted_sum = karis_brightness_weighted_sum( - center, right_far, lower_right_far, lower_far); - float4 lower_left_weighted_sum = karis_brightness_weighted_sum( - left_far, center, lower_far, lower_left_far); - - /* The original weights equation mentioned in slide 153 is: - * 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1 - * Multiply both sides by 8 and you get: - * 4 + 1 + 1 + 1 + 1 = 8 - * So the weights are as used in the following code section. */ - float4 result = (4.0f / 8.0f) * center_weighted_sum + - (1.0f / 8.0f) * (upper_left_weighted_sum + upper_right_weighted_sum + - lower_left_weighted_sum + lower_right_weighted_sum); - copy_v4_v4(output.get_elem(texel.x, texel.y), result); - } - } - } - }); -} - -/* Progressively down-sample the given buffer into a buffer with half the size for the given - * chain length, returning an array containing the chain of down-sampled buffers. The first - * buffer of the chain is the given buffer itself for easier handling. The chain length is - * expected not to exceed the binary logarithm of the smaller dimension of the given buffer, - * because that would buffer in down-sampling passes that produce useless textures with just - * one pixel. */ -static Array> compute_bloom_downsample_chain( - MemoryBuffer &highlights, int chain_length) -{ - Array> downsample_chain(chain_length); - - /* We append the original highlights buffer to the first buffer of the chain to make the code - * easier. In turn, the number of passes is one less than the chain length, because the first - * buffer needn't be computed. */ - downsample_chain[0] = std::make_unique(highlights); - const IndexRange downsample_passes_range(chain_length - 1); - - for (const int i : downsample_passes_range) { - const MemoryBuffer &input = *downsample_chain[i]; - - const int2 input_size = int2(input.get_width(), input.get_height()); - const int2 output_size = input_size / 2; - - rcti output_rect; - BLI_rcti_init(&output_rect, 0, output_size.x, 0, output_size.y); - downsample_chain[i + 1] = std::make_unique(DataType::Color, output_rect, false); - MemoryBuffer &output = *downsample_chain[i + 1]; - - /* For the first down-sample pass, we use a special "Karis" down-sample pass that applies a - * form of local tone mapping to reduce the contributions of fireflies, see the shader for - * more information. Later passes use a simple average down-sampling filter because fireflies - * doesn't service the first pass. */ - const bool use_karis_average = i == downsample_passes_range.first(); - downsample(input, output, use_karis_average); - } - - return downsample_chain; -} - -/* The size of the bloom relative to its maximum possible size, see the - * compute_bloom_size_halving_count() method for more information. */ -static int get_bloom_size(const NodeGlare *settings) -{ - return settings->size; -} - -/* The bloom has a maximum possible size when the bloom size is equal to MAX_GLARE_SIZE and - * halves for every unit decrement of the bloom size. This method computes the number of halving - * that should take place, which is simply the difference to MAX_GLARE_SIZE. */ -static int compute_bloom_size_halving_count(const NodeGlare *settings) -{ - return MAX_GLARE_SIZE - get_bloom_size(settings); -} - -/* Bloom is computed by first progressively half-down-sampling the highlights down to a certain - * size, then progressively double-up-sampling the last down-sampled buffer up to the original size - * of the highlights, adding the down-sampled buffer of the same size in each up-sampling step. - * This can be illustrated as follows: - * - * Highlights ---+---> Bloom - * | | - * Down-sampled ---+---> Up-sampled - * | | - * Down-sampled ---+---> Up-sampled - * | | - * Down-sampled ---+---> Up-sampled - * | ^ - * ... | - * Down-sampled ------------' - * - * The smooth down-sampling followed by smooth up-sampling can be thought of as a cheap way to - * approximate a large radius blur, and adding the corresponding down-sampled buffer while - * up-sampling is done to counter the attenuation that happens during down-sampling. - * - * Smaller down-sampled buffers contribute to larger glare size, so controlling the size can be - * done by stopping down-sampling down to a certain size, where the maximum possible size is - * achieved when down-sampling happens down to the smallest size of 2. */ -void GlareBloomOperation::generate_glare(float *output, - MemoryBuffer *highlights, - const NodeGlare *settings) -{ - /* The maximum possible glare size is achieved when we down-sampled down to the smallest size - * of 2, which would buffer in a down-sampling chain length of the binary logarithm of the - * smaller dimension of the size of the highlights. - * - * However, as users might want a smaller glare size, we reduce the chain length by the halving - * count supplied by the user. */ - const int2 size = int2(highlights->get_width(), highlights->get_height()); - const int smaller_glare_dimension = math::min(size.x, size.y); - const int chain_length = int(std::log2(smaller_glare_dimension)) - - compute_bloom_size_halving_count(settings); - - /* If the chain length is less than 2, that means no down-sampling will happen, so we just copy - * the highlights to the output. This is a sanitization of a corner case, so no need to worry - * about optimizing the copy away. */ - if (chain_length < 2) { - memcpy(output, - highlights->get_buffer(), - size.x * size.y * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); - return; - } - - Array> downsample_chain = compute_bloom_downsample_chain( - *highlights, chain_length); - - /* Notice that for a chain length of n, we need (n - 1) up-sampling passes. */ - const IndexRange upsample_passes_range(chain_length - 1); - - for (const int i : upsample_passes_range) { - const MemoryBuffer &input = *downsample_chain[upsample_passes_range.last() - i + 1]; - MemoryBuffer &output = *downsample_chain[upsample_passes_range.last() - i]; - upsample(input, output); - } - - memcpy(output, - downsample_chain[0]->get_buffer(), - size.x * size.y * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareBloomOperation.h b/source/blender/compositor/operations/COM_GlareBloomOperation.h deleted file mode 100644 index 9ec9935e226..00000000000 --- a/source/blender/compositor/operations/COM_GlareBloomOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GlareBaseOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class GlareBloomOperation : public GlareBaseOperation { - public: - GlareBloomOperation() : GlareBaseOperation() {} - - protected: - void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc deleted file mode 100644 index a9df56f65a5..00000000000 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include -#include - -#if defined(WITH_FFTW3) -# include -#endif - -#include "BLI_enumerable_thread_specific.hh" -#include "BLI_fftw.hh" -#include "BLI_index_range.hh" -#include "BLI_math_base.hh" -#include "BLI_math_vector_types.hh" -#include "BLI_task.hh" - -#include "COM_GlareFogGlowOperation.h" - -namespace blender::compositor { - -/* Given the x and y location in the range from 0 to kernel_size - 1, where kernel_size is odd, - * compute the fog glow kernel value. The equations are arbitrary and were chosen using visual - * judgment. The kernel is not normalized and need normalization. */ -[[maybe_unused]] static float compute_fog_glow_kernel_value(int x, int y, int kernel_size) -{ - const int half_kernel_size = kernel_size / 2; - const float scale = 0.25f * math::sqrt(math::square(kernel_size)); - const float v = ((y - half_kernel_size) / float(half_kernel_size)); - const float u = ((x - half_kernel_size) / float(half_kernel_size)); - const float r = (math::square(u) + math::square(v)) * scale; - const float d = -math::sqrt(math::sqrt(math::sqrt(r))) * 9.0f; - const float kernel_value = math::exp(d); - - const float window = (0.5f + 0.5f * math::cos(u * math::numbers::pi)) * - (0.5f + 0.5f * math::cos(v * math::numbers::pi)); - const float windowed_kernel_value = window * kernel_value; - - return windowed_kernel_value; -} - -void GlareFogGlowOperation::generate_glare(float *output, - MemoryBuffer *image, - const NodeGlare *settings) -{ -#if defined(WITH_FFTW3) - fftw::initialize_float(); - - /* We use an odd sized kernel since an even one will typically introduce a tiny offset as it has - * no exact center value. */ - const int kernel_size = (1 << settings->size) + 1; - - /* Since we will be doing a circular convolution, we need to zero pad our input image by half the - * kernel size to avoid the kernel affecting the pixels at the other side of image. Therefore, - * zero boundary is assumed. */ - const int needed_padding_amount = kernel_size / 2; - const int2 image_size = int2(image->get_width(), image->get_height()); - const int2 needed_spatial_size = image_size + needed_padding_amount; - const int2 spatial_size = fftw::optimal_size_for_real_transform(needed_spatial_size); - - /* The FFTW real to complex transforms utilizes the hermitian symmetry of real transforms and - * stores only half the output since the other half is redundant, so we only allocate half of the - * first dimension. See Section 4.3.4 Real-data DFT Array Format in the FFTW manual for more - * information. */ - const int2 frequency_size = int2(spatial_size.x / 2 + 1, spatial_size.y); - - float *kernel_spatial_domain = fftwf_alloc_real(spatial_size.x * spatial_size.y); - std::complex *kernel_frequency_domain = reinterpret_cast *>( - fftwf_alloc_complex(frequency_size.x * frequency_size.y)); - - /* Create a real to complex plan to transform the kernel to the frequency domain, but the same - * plan will be used for the image since they both have the same dimensions. */ - fftwf_plan forward_plan = fftwf_plan_dft_r2c_2d( - spatial_size.y, - spatial_size.x, - kernel_spatial_domain, - reinterpret_cast(kernel_frequency_domain), - FFTW_ESTIMATE); - - /* Use a double to sum the kernel since floats are not stable with threaded summation. */ - threading::EnumerableThreadSpecific sum_by_thread([]() { return 0.0; }); - - /* Compute the kernel while zero padding to match the padded image size. */ - threading::parallel_for(IndexRange(spatial_size.y), 1, [&](const IndexRange sub_y_range) { - double &sum = sum_by_thread.local(); - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(spatial_size.x)) { - /* We offset the computed kernel with wrap around such that it is centered at the zero - * point, which is the expected format for doing circular convolutions in the frequency - * domain. */ - const int half_kernel_size = kernel_size / 2; - int64_t output_x = mod_i(x - half_kernel_size, spatial_size.x); - int64_t output_y = mod_i(y - half_kernel_size, spatial_size.y); - - const bool is_inside_kernel = x < kernel_size && y < kernel_size; - if (is_inside_kernel) { - const float kernel_value = compute_fog_glow_kernel_value(x, y, kernel_size); - kernel_spatial_domain[output_x + output_y * spatial_size.x] = kernel_value; - sum += kernel_value; - } - else { - kernel_spatial_domain[output_x + output_y * spatial_size.x] = 0.0f; - } - } - } - }); - - /* Instead of normalizing the kernel now, we normalize it in the frequency domain since we will - * be doing sample normalization anyways. This is okay since the Fourier transform is linear. */ - const float kernel_normalization_factor = float( - std::accumulate(sum_by_thread.begin(), sum_by_thread.end(), 0.0)); - - fftwf_execute_dft_r2c(forward_plan, - kernel_spatial_domain, - reinterpret_cast(kernel_frequency_domain)); - fftwf_free(kernel_spatial_domain); - - /* We only process the color channels, the alpha channel is written to the output as is. */ - const int channels_count = 3; - const int64_t spatial_pixels_per_channel = int64_t(spatial_size.x) * spatial_size.y; - const int64_t frequency_pixels_per_channel = int64_t(frequency_size.x) * frequency_size.y; - const int64_t spatial_pixels_count = spatial_pixels_per_channel * channels_count; - const int64_t frequency_pixels_count = frequency_pixels_per_channel * channels_count; - - float *image_spatial_domain = fftwf_alloc_real(spatial_pixels_count); - std::complex *image_frequency_domain = reinterpret_cast *>( - fftwf_alloc_complex(frequency_pixels_count)); - - /* Zero pad the image to the required spatial domain size, storing each channel in planar - * format for better cache locality, that is, RRRR...GGGG...BBBB. */ - threading::parallel_for(IndexRange(spatial_size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(spatial_size.x)) { - const bool is_inside_image = x < image_size.x && y < image_size.y; - for (const int64_t channel : IndexRange(channels_count)) { - const int64_t base_index = x + y * spatial_size.x; - const int64_t output_index = base_index + spatial_pixels_per_channel * channel; - if (is_inside_image) { - image_spatial_domain[output_index] = image->get_elem(x, y)[channel]; - } - else { - image_spatial_domain[output_index] = 0.0f; - } - } - } - } - }); - - threading::parallel_for(IndexRange(channels_count), 1, [&](const IndexRange sub_range) { - for (const int64_t channel : sub_range) { - fftwf_execute_dft_r2c(forward_plan, - image_spatial_domain + spatial_pixels_per_channel * channel, - reinterpret_cast(image_frequency_domain) + - frequency_pixels_per_channel * channel); - } - }); - - /* Multiply the kernel and the image in the frequency domain to perform the convolution. The - * FFT is not normalized, meaning the result of the FFT followed by an inverse FFT will result - * in an image that is scaled by a factor of the product of the width and height, so we take - * that into account by dividing by that scale. See Section 4.8.6 Multi-dimensional Transforms of - * the FFTW manual for more information. */ - const float normalization_scale = float(spatial_size.x) * spatial_size.y * - kernel_normalization_factor; - threading::parallel_for(IndexRange(frequency_size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t channel : IndexRange(channels_count)) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(frequency_size.x)) { - const int64_t base_index = x + y * frequency_size.x; - const int64_t output_index = base_index + frequency_pixels_per_channel * channel; - const std::complex kernel_value = kernel_frequency_domain[base_index]; - image_frequency_domain[output_index] *= kernel_value / normalization_scale; - } - } - } - }); - - /* Create a complex to real plan to transform the image to the real domain. */ - fftwf_plan backward_plan = fftwf_plan_dft_c2r_2d( - spatial_size.y, - spatial_size.x, - reinterpret_cast(image_frequency_domain), - image_spatial_domain, - FFTW_ESTIMATE); - - threading::parallel_for(IndexRange(channels_count), 1, [&](const IndexRange sub_range) { - for (const int64_t channel : sub_range) { - fftwf_execute_dft_c2r(backward_plan, - reinterpret_cast(image_frequency_domain) + - frequency_pixels_per_channel * channel, - image_spatial_domain + spatial_pixels_per_channel * channel); - } - }); - - /* Copy the result to the output. */ - threading::parallel_for(IndexRange(image_size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(image_size.x)) { - for (const int64_t channel : IndexRange(channels_count)) { - const int64_t output_index = (x + y * image_size.x) * image->get_num_channels(); - const int64_t base_index = x + y * spatial_size.x; - const int64_t input_index = base_index + spatial_pixels_per_channel * channel; - output[output_index + channel] = image_spatial_domain[input_index]; - output[output_index + 3] = image->get_buffer()[output_index + 3]; - } - } - } - }); - - fftwf_destroy_plan(forward_plan); - fftwf_destroy_plan(backward_plan); - fftwf_free(image_spatial_domain); - fftwf_free(image_frequency_domain); - fftwf_free(kernel_frequency_domain); -#else - UNUSED_VARS(output, image, settings); -#endif -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h deleted file mode 100644 index e7cd447b68e..00000000000 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GlareBaseOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class GlareFogGlowOperation : public GlareBaseOperation { - public: - GlareFogGlowOperation() : GlareBaseOperation() {} - - protected: - void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cc b/source/blender/compositor/operations/COM_GlareGhostOperation.cc deleted file mode 100644 index 38c566b9d89..00000000000 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GlareGhostOperation.h" -#include "COM_FastGaussianBlurOperation.h" - -namespace blender::compositor { - -static float smooth_mask(float x, float y) -{ - float t; - x = 2.0f * x - 1.0f; - y = 2.0f * y - 1.0f; - if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) { - return t; - } - - return 0.0f; -} - -void GlareGhostOperation::generate_glare(float *data, - MemoryBuffer *input_tile, - const NodeGlare *settings) -{ - const int qt = 1 << settings->quality; - const float s1 = 4.0f / float(qt), s2 = 2.0f * s1; - int x, y, n, p, np; - fRGB c, tc, cm[64]; - float sc, isc, u, v, sm, s, t, ofs, scalef[64]; - const float cmo = 1.0f - settings->colmod; - - MemoryBuffer gbuf(*input_tile); - MemoryBuffer tbuf1(*input_tile); - - bool breaked = false; - - FastGaussianBlurOperation::IIR_gauss(&tbuf1, s1, 0, 3); - if (!breaked) { - FastGaussianBlurOperation::IIR_gauss(&tbuf1, s1, 1, 3); - } - if (is_braked()) { - breaked = true; - } - if (!breaked) { - FastGaussianBlurOperation::IIR_gauss(&tbuf1, s1, 2, 3); - } - - MemoryBuffer tbuf2(tbuf1); - - if (is_braked()) { - breaked = true; - } - if (!breaked) { - FastGaussianBlurOperation::IIR_gauss(&tbuf2, s2, 0, 3); - } - if (is_braked()) { - breaked = true; - } - if (!breaked) { - FastGaussianBlurOperation::IIR_gauss(&tbuf2, s2, 1, 3); - } - if (is_braked()) { - breaked = true; - } - if (!breaked) { - FastGaussianBlurOperation::IIR_gauss(&tbuf2, s2, 2, 3); - } - - ofs = (settings->iter & 1) ? 0.5f : 0.0f; - for (x = 0; x < (settings->iter * 4); x++) { - y = x & 3; - cm[x][0] = cm[x][1] = cm[x][2] = 1; - if (y == 1) { - fRGB_rgbmult(cm[x], 1.0f, cmo, cmo); - } - if (y == 2) { - fRGB_rgbmult(cm[x], cmo, cmo, 1.0f); - } - if (y == 3) { - fRGB_rgbmult(cm[x], cmo, 1.0f, cmo); - } - scalef[x] = 2.1f * (1.0f - (x + ofs) / float(settings->iter * 4)); - if (x & 1) { - scalef[x] = -0.99f / scalef[x]; - } - } - - sc = 2.13; - isc = -0.97; - for (y = 0; y < gbuf.get_height() && (!breaked); y++) { - v = (float(y) + 0.5f) / float(gbuf.get_height()); - for (x = 0; x < gbuf.get_width(); x++) { - u = (float(x) + 0.5f) / float(gbuf.get_width()); - s = (u - 0.5f) * sc + 0.5f; - t = (v - 0.5f) * sc + 0.5f; - tbuf1.read_bilinear(c, s * gbuf.get_width(), t * gbuf.get_height()); - sm = smooth_mask(s, t); - mul_v3_fl(c, sm); - s = (u - 0.5f) * isc + 0.5f; - t = (v - 0.5f) * isc + 0.5f; - tbuf2.read_bilinear(tc, s * gbuf.get_width() - 0.5f, t * gbuf.get_height() - 0.5f); - sm = smooth_mask(s, t); - madd_v3_v3fl(c, tc, sm); - - gbuf.write_pixel(x, y, c); - } - if (is_braked()) { - breaked = true; - } - } - - memset(tbuf1.get_buffer(), - 0, - tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); - for (n = 1; n < settings->iter && (!breaked); n++) { - for (y = 0; y < gbuf.get_height() && (!breaked); y++) { - v = (float(y) + 0.5f) / float(gbuf.get_height()); - for (x = 0; x < gbuf.get_width(); x++) { - u = (float(x) + 0.5f) / float(gbuf.get_width()); - tc[0] = tc[1] = tc[2] = 0.0f; - for (p = 0; p < 4; p++) { - np = (n << 2) + p; - s = (u - 0.5f) * scalef[np] + 0.5f; - t = (v - 0.5f) * scalef[np] + 0.5f; - gbuf.read_bilinear(c, s * gbuf.get_width() - 0.5f, t * gbuf.get_height() - 0.5f); - mul_v3_v3(c, cm[np]); - sm = smooth_mask(s, t) * 0.25f; - madd_v3_v3fl(tc, c, sm); - } - tbuf1.add_pixel(x, y, tc); - } - if (is_braked()) { - breaked = true; - } - } - memcpy(gbuf.get_buffer(), - tbuf1.get_buffer(), - tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); - } - memcpy(data, - gbuf.get_buffer(), - gbuf.get_width() * gbuf.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h deleted file mode 100644 index 624826f65bb..00000000000 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GlareBaseOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class GlareGhostOperation : public GlareBaseOperation { - public: - GlareGhostOperation() : GlareBaseOperation() {} - - protected: - void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cc b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cc deleted file mode 100644 index d8fad502689..00000000000 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GlareSimpleStarOperation.h" - -namespace blender::compositor { - -void GlareSimpleStarOperation::generate_glare(float *data, - MemoryBuffer *input_tile, - const NodeGlare *settings) -{ - int i, x, y, ym, yp, xm, xp; - float c[4] = {0, 0, 0, 0}, tc[4] = {0, 0, 0, 0}; - const float f1 = 1.0f - settings->fade; - const float f2 = (1.0f - f1) * 0.5f; - - MemoryBuffer tbuf1(*input_tile); - MemoryBuffer tbuf2(*input_tile); - - bool breaked = false; - for (i = 0; i < settings->iter && (!breaked); i++) { - // // (x || x-1, y-1) to (x || x+1, y+1) - // // F - for (y = 0; y < this->get_height() && (!breaked); y++) { - ym = y - i; - yp = y + i; - for (x = 0; x < this->get_width(); x++) { - xm = x - i; - xp = x + i; - tbuf1.read(c, x, y); - mul_v3_fl(c, f1); - tbuf1.read(tc, (settings->star_45 ? xm : x), ym); - madd_v3_v3fl(c, tc, f2); - tbuf1.read(tc, (settings->star_45 ? xp : x), yp); - madd_v3_v3fl(c, tc, f2); - c[3] = 1.0f; - tbuf1.write_pixel(x, y, c); - - tbuf2.read(c, x, y); - mul_v3_fl(c, f1); - tbuf2.read(tc, xm, (settings->star_45 ? yp : y)); - madd_v3_v3fl(c, tc, f2); - tbuf2.read(tc, xp, (settings->star_45 ? ym : y)); - madd_v3_v3fl(c, tc, f2); - c[3] = 1.0f; - tbuf2.write_pixel(x, y, c); - } - if (is_braked()) { - breaked = true; - } - } - // // B - for (y = this->get_height() - 1; y >= 0 && (!breaked); y--) { - ym = y - i; - yp = y + i; - for (x = this->get_width() - 1; x >= 0; x--) { - xm = x - i; - xp = x + i; - tbuf1.read(c, x, y); - mul_v3_fl(c, f1); - tbuf1.read(tc, (settings->star_45 ? xm : x), ym); - madd_v3_v3fl(c, tc, f2); - tbuf1.read(tc, (settings->star_45 ? xp : x), yp); - madd_v3_v3fl(c, tc, f2); - c[3] = 1.0f; - tbuf1.write_pixel(x, y, c); - - tbuf2.read(c, x, y); - mul_v3_fl(c, f1); - tbuf2.read(tc, xm, (settings->star_45 ? yp : y)); - madd_v3_v3fl(c, tc, f2); - tbuf2.read(tc, xp, (settings->star_45 ? ym : y)); - madd_v3_v3fl(c, tc, f2); - c[3] = 1.0f; - tbuf2.write_pixel(x, y, c); - } - if (is_braked()) { - breaked = true; - } - } - } - - for (i = 0; i < this->get_width() * this->get_height() * 4; i++) { - data[i] = tbuf1.get_buffer()[i] + tbuf2.get_buffer()[i]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h deleted file mode 100644 index 881170af17e..00000000000 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GlareBaseOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class GlareSimpleStarOperation : public GlareBaseOperation { - public: - GlareSimpleStarOperation() : GlareBaseOperation() {} - - protected: - void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc deleted file mode 100644 index ca436b7d797..00000000000 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_GlareStreaksOperation.h" -#include "BLI_math_rotation.h" - -namespace blender::compositor { - -void GlareStreaksOperation::generate_glare(float *data, - MemoryBuffer *input_tile, - const NodeGlare *settings) -{ - int x, y, n; - // uint nump = 0; /* UNUSED. */ - float c1[4], c2[4], c3[4], c4[4]; - float a, ang = DEG2RADF(360.0f) / float(settings->streaks); - - int size = input_tile->get_width() * input_tile->get_height(); - int size4 = size * 4; - - bool breaked = false; - - MemoryBuffer tsrc(*input_tile); - MemoryBuffer tdst(DataType::Color, input_tile->get_rect()); - tdst.clear(); - memset(data, 0, size4 * sizeof(float)); - - for (a = 0.0f; a < DEG2RADF(360.0f) && (!breaked); a += ang) { - const float an = a + settings->angle_ofs; - const float vx = cos(double(an)), vy = sin(double(an)); - for (n = 0; n < settings->iter && (!breaked); n++) { - const float p4 = pow(4.0, double(n)); - const float vxp = vx * p4, vyp = vy * p4; - const float wt = pow(double(settings->fade), double(p4)); - - /* Color-modulation amount relative to current pass. */ - const float cmo = 1.0f - float(pow(double(settings->colmod), double(n) + 1)); - - float *tdstcol = tdst.get_buffer(); - for (y = 0; y < tsrc.get_height() && (!breaked); y++) { - for (x = 0; x < tsrc.get_width(); x++, tdstcol += 4) { - /* First pass no offset, always same for every pass, exact copy, - * otherwise results in uneven brightness, only need once. */ - if (n == 0) { - tsrc.read(c1, x, y); - } - else { - c1[0] = c1[1] = c1[2] = 0; - } - tsrc.read_bilinear(c2, x + vxp, y + vyp); - tsrc.read_bilinear(c3, x + vxp * 2.0f, y + vyp * 2.0f); - tsrc.read_bilinear(c4, x + vxp * 3.0f, y + vyp * 3.0f); - /* Modulate color to look vaguely similar to a color spectrum. */ - c2[1] *= cmo; - c2[2] *= cmo; - - c3[0] *= cmo; - c3[1] *= cmo; - - c4[0] *= cmo; - c4[2] *= cmo; - - tdstcol[0] = 0.5f * (tdstcol[0] + c1[0] + wt * (c2[0] + wt * (c3[0] + wt * c4[0]))); - tdstcol[1] = 0.5f * (tdstcol[1] + c1[1] + wt * (c2[1] + wt * (c3[1] + wt * c4[1]))); - tdstcol[2] = 0.5f * (tdstcol[2] + c1[2] + wt * (c2[2] + wt * (c3[2] + wt * c4[2]))); - tdstcol[3] = 1.0f; - } - if (is_braked()) { - breaked = true; - } - } - memcpy(tsrc.get_buffer(), tdst.get_buffer(), sizeof(float) * size4); - } - - float *sourcebuffer = tsrc.get_buffer(); - float factor = 1.0f / float(6 - settings->iter); - for (int i = 0; i < size4; i += 4) { - madd_v3_v3fl(&data[i], &sourcebuffer[i], factor); - data[i + 3] = 1.0f; - } - - tdst.clear(); - memcpy(tsrc.get_buffer(), input_tile->get_buffer(), sizeof(float) * size4); - // nump++; /* UNUSED. */ - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h deleted file mode 100644 index 53151504895..00000000000 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_GlareBaseOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class GlareStreaksOperation : public GlareBaseOperation { - public: - GlareStreaksOperation() : GlareBaseOperation() {} - - protected: - void generate_glare(float *data, MemoryBuffer *input_tile, const NodeGlare *settings) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cc b/source/blender/compositor/operations/COM_GlareThresholdOperation.cc deleted file mode 100644 index c38efba59c8..00000000000 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_base.hh" -#include "BLI_math_color.h" -#include "BLI_utildefines.h" - -#include "COM_GlareThresholdOperation.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -GlareThresholdOperation::GlareThresholdOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::FitAny); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; -} - -void GlareThresholdOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - NodeOperation::determine_canvas(preferred_area, r_area); - const int width = BLI_rcti_size_x(&r_area) / (1 << settings_->quality); - const int height = BLI_rcti_size_y(&r_area) / (1 << settings_->quality); - r_area.xmax = r_area.xmin + width; - r_area.ymax = r_area.ymin + height; -} - -void GlareThresholdOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const float threshold = settings_->threshold; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - float4 hsva; - rgb_to_hsv_v(it.in(0), hsva); - - hsva.z = math::max(0.0f, hsva.z - threshold); - - hsv_to_rgb_v(hsva, it.out); - CLAMP3_MIN(it.out, 0.0f); - it.out[3] = 1.0f; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h deleted file mode 100644 index 0f2f535b52a..00000000000 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_light_types.h" - -namespace blender::compositor { - -class GlareThresholdOperation : public MultiThreadedOperation { - private: - /** - * \brief settings of the glare node. - */ - const NodeGlare *settings_; - - public: - GlareThresholdOperation(); - - void set_glare_settings(const NodeGlare *settings) - { - settings_ = settings; - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cc b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cc deleted file mode 100644 index 3945ce793e7..00000000000 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_HueSaturationValueCorrectOperation.h" - -#include "BLI_math_vector.h" - -#include "BKE_colortools.hh" - -namespace blender::compositor { - -HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void HueSaturationValueCorrectOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - float hsv[4]; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - copy_v4_v4(hsv, it.in(0)); - - /* We parameterize the curve using the hue value. */ - const float parameter = hsv[0]; - - /* Adjust hue, scaling returned default 0.5 up to 1. */ - float f = BKE_curvemapping_evaluateF(curve_mapping_, 0, parameter); - hsv[0] += f - 0.5f; - - /* Adjust saturation, scaling returned default 0.5 up to 1. */ - f = BKE_curvemapping_evaluateF(curve_mapping_, 1, parameter); - hsv[1] *= (f * 2.0f); - - /* Adjust value, scaling returned default 0.5 up to 1. */ - f = BKE_curvemapping_evaluateF(curve_mapping_, 2, parameter); - hsv[2] *= (f * 2.0f); - - hsv[0] = hsv[0] - floorf(hsv[0]); /* Mod 1.0. */ - CLAMP(hsv[1], 0.0f, 1.0f); - - copy_v4_v4(it.out, hsv); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h deleted file mode 100644 index 444325d4b7b..00000000000 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_CurveBaseOperation.h" - -namespace blender::compositor { - -class HueSaturationValueCorrectOperation : public CurveBaseOperation { - public: - HueSaturationValueCorrectOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cc b/source/blender/compositor/operations/COM_IDMaskOperation.cc deleted file mode 100644 index 15b6a24f168..00000000000 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_IDMaskOperation.h" - -namespace blender::compositor { - -IDMaskOperation::IDMaskOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - flags_.can_be_constant = true; -} - -void IDMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - const int width = BLI_rcti_size_x(&area); - for (int y = area.ymin; y < area.ymax; y++) { - float *out = output->get_elem(area.xmin, y); - const float *in = input->get_elem(area.xmin, y); - const float *row_end = out + width * output->elem_stride; - while (out < row_end) { - out[0] = (roundf(in[0]) == object_index_) ? 1.0f : 0.0f; - in += input->elem_stride; - out += output->elem_stride; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h deleted file mode 100644 index 814316eeec2..00000000000 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class IDMaskOperation : public MultiThreadedOperation { - private: - float object_index_; - - public: - IDMaskOperation(); - - void set_object_index(float object_index) - { - object_index_ = object_index; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc deleted file mode 100644 index 4ba20d90fa8..00000000000 --- a/source/blender/compositor/operations/COM_ImageOperation.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ImageOperation.h" - -#include "BKE_scene.hh" - -#include "IMB_colormanagement.hh" -#include "IMB_interp.hh" - -namespace blender::compositor { - -BaseImageOperation::BaseImageOperation() -{ - image_ = nullptr; - buffer_ = nullptr; - image_user_ = {}; - imagewidth_ = 0; - imageheight_ = 0; - framenumber_ = 0; - number_of_channels_ = 0; - rd_ = nullptr; - view_name_ = nullptr; -} -ImageOperation::ImageOperation() : BaseImageOperation() -{ - this->add_output_socket(DataType::Color); -} -ImageAlphaOperation::ImageAlphaOperation() : BaseImageOperation() -{ - this->add_output_socket(DataType::Value); -} - -ImBuf *BaseImageOperation::get_im_buf() -{ - if (rd_ == nullptr || image_ == nullptr) { - return nullptr; - } - - ImBuf *ibuf = BKE_image_acquire_multilayer_view_ibuf(*rd_, *image_, image_user_, "", view_name_); - if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) - { - BKE_image_release_ibuf(image_, ibuf, nullptr); - return nullptr; - } - return ibuf; -} - -void BaseImageOperation::init_execution() -{ - ImBuf *stackbuf = get_im_buf(); - buffer_ = stackbuf; - if (stackbuf) { - imagewidth_ = stackbuf->x; - imageheight_ = stackbuf->y; - number_of_channels_ = stackbuf->channels; - } -} - -void BaseImageOperation::deinit_execution() -{ - BKE_image_release_ibuf(image_, buffer_, nullptr); -} - -void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - ImBuf *stackbuf = get_im_buf(); - - r_area = COM_AREA_NONE; - - if (stackbuf) { - BLI_rcti_init(&r_area, 0, stackbuf->x, 0, stackbuf->y); - } - - BKE_image_release_ibuf(image_, stackbuf, nullptr); -} - -void ImageOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - const bool ensure_premultiplied = !ELEM( - image_->alpha_mode, IMA_ALPHA_CHANNEL_PACKED, IMA_ALPHA_IGNORE); - if (buffer_) { - output->copy_from(buffer_, area, ensure_premultiplied, true); - } - else { - output->fill(area, COM_COLOR_TRANSPARENT); - } -} - -void ImageAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - if (buffer_) { - output->copy_from(buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); - } - else { - output->fill(area, COM_VALUE_ZERO); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h deleted file mode 100644 index b70f0144763..00000000000 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BKE_image.hh" -#include "BLI_listbase.h" -#include "BLI_sys_types.h" -#include "BLI_utildefines.h" -#include "COM_MultiThreadedOperation.h" -#include "MEM_guardedalloc.h" - -#include "RE_pipeline.h" -#include "RE_texture.h" - -namespace blender::compositor { - -/** - * \brief Base class for all image operations - */ -class BaseImageOperation : public MultiThreadedOperation { - protected: - ImBuf *buffer_; - Image *image_; - ImageUser image_user_; - - int imageheight_; - int imagewidth_; - int framenumber_; - int number_of_channels_; - const RenderData *rd_; - const char *view_name_; - - BaseImageOperation(); - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - virtual ImBuf *get_im_buf(); - - public: - void init_execution() override; - void deinit_execution() override; - void set_image(Image *image) - { - image_ = image; - } - void set_image_user(const ImageUser &imageuser) - { - image_user_ = imageuser; - } - void set_render_data(const RenderData *rd) - { - rd_ = rd; - } - void set_view_name(const char *view_name) - { - view_name_ = view_name; - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } -}; -class ImageOperation : public BaseImageOperation { - public: - /** - * Constructor - */ - ImageOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; -class ImageAlphaOperation : public BaseImageOperation { - public: - /** - * Constructor - */ - ImageAlphaOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cc b/source/blender/compositor/operations/COM_InpaintOperation.cc deleted file mode 100644 index bdfc4b9d82e..00000000000 --- a/source/blender/compositor/operations/COM_InpaintOperation.cc +++ /dev/null @@ -1,202 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_array.hh" -#include "BLI_math_base.hh" -#include "BLI_math_numbers.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_span.hh" -#include "BLI_task.hh" - -#include "COM_InpaintOperation.h" -#include "COM_JumpFloodingAlgorithm.h" -#include "COM_SymmetricSeparableBlurVariableSizeAlgorithm.h" - -namespace blender::compositor { - -void InpaintSimpleOperation::compute_inpainting_region( - const MemoryBuffer *input, - const MemoryBuffer &inpainted_region, - const MemoryBuffer &distance_to_boundary_buffer, - MemoryBuffer *output) -{ - const int2 size = int2(this->get_width(), this->get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - float4 color = float4(input->get_elem(x, y)); - - if (color.w == 1.0f) { - copy_v4_v4(output->get_elem(x, y), color); - continue; - } - - float distance_to_boundary = *distance_to_boundary_buffer.get_elem(x, y); - - if (distance_to_boundary > max_distance_) { - copy_v4_v4(output->get_elem(x, y), color); - continue; - } - - float4 inpainted_color = float4(inpainted_region.get_elem(x, y)); - float4 final_color = float4(math::interpolate(inpainted_color, color, color.w).xyz(), - 1.0f); - copy_v4_v4(output->get_elem(x, y), final_color); - } - } - }); -} - -void InpaintSimpleOperation::fill_inpainting_region(const MemoryBuffer *input, - Span flooded_boundary, - MemoryBuffer &filled_region, - MemoryBuffer &distance_to_boundary_buffer, - MemoryBuffer &smoothing_radius_buffer) -{ - const int2 size = int2(this->get_width(), this->get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - const size_t index = size_t(y) * size.x + x; - - float4 color = float4(input->get_elem(x, y)); - - if (color.w == 1.0f) { - copy_v4_v4(filled_region.get_elem(x, y), color); - *smoothing_radius_buffer.get_elem(x, y) = 0.0f; - *distance_to_boundary_buffer.get_elem(x, y) = 0.0f; - continue; - } - - int2 closest_boundary_texel = flooded_boundary[index]; - float distance_to_boundary = math::distance(float2(texel), float2(closest_boundary_texel)); - *distance_to_boundary_buffer.get_elem(x, y) = distance_to_boundary; - - float blur_window_size = math::min(float(max_distance_), distance_to_boundary) / - math::numbers::sqrt2; - bool skip_smoothing = distance_to_boundary > (max_distance_ * 2.0f); - float smoothing_radius = skip_smoothing ? 0.0f : blur_window_size; - *smoothing_radius_buffer.get_elem(x, y) = smoothing_radius; - - float4 boundary_color = float4( - input->get_elem_clamped(closest_boundary_texel.x, closest_boundary_texel.y)); - float4 final_color = math::interpolate(boundary_color, color, color.w); - copy_v4_v4(filled_region.get_elem(x, y), final_color); - } - } - }); -} - -Array InpaintSimpleOperation::compute_inpainting_boundary(const MemoryBuffer *input) -{ - const int2 size = int2(this->get_width(), this->get_height()); - Array boundary(size_t(size.x) * size.y); - - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - - bool has_transparent_neighbors = false; - for (int j = -1; j <= 1; j++) { - for (int i = -1; i <= 1; i++) { - int2 offset = int2(i, j); - - if (offset != int2(0)) { - if (float4(input->get_elem_clamped(x + i, y + j)).w < 1.0f) { - has_transparent_neighbors = true; - break; - } - } - } - } - - bool is_opaque = float4(input->get_elem(x, y)).w == 1.0f; - bool is_boundary_pixel = is_opaque && has_transparent_neighbors; - - int2 jump_flooding_value = initialize_jump_flooding_value(texel, is_boundary_pixel); - - const size_t index = size_t(y) * size.x + x; - boundary[index] = jump_flooding_value; - } - } - }); - - return boundary; -} - -/* Identical to realtime_compositor::InpaintOperation::execute see that function, its - * sub-functions and shaders for more details. */ -void InpaintSimpleOperation::inpaint(const MemoryBuffer *input, MemoryBuffer *output) -{ - const int2 size = int2(this->get_width(), this->get_height()); - Array inpainting_boundary = compute_inpainting_boundary(input); - Array flooded_boundary = jump_flooding(inpainting_boundary, size); - - MemoryBuffer filled_region(DataType::Color, input->get_rect()); - MemoryBuffer distance_to_boundary(DataType::Value, input->get_rect()); - MemoryBuffer smoothing_radius(DataType::Value, input->get_rect()); - fill_inpainting_region( - input, flooded_boundary, filled_region, distance_to_boundary, smoothing_radius); - - MemoryBuffer smoothed_region(DataType::Color, input->get_rect()); - symmetric_separable_blur_variable_size( - filled_region, smoothed_region, smoothing_radius, R_FILTER_GAUSS, max_distance_); - - compute_inpainting_region(input, smoothed_region, distance_to_boundary, output); -} - -InpaintSimpleOperation::InpaintSimpleOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - cached_buffer_ = nullptr; - cached_buffer_ready_ = false; - flags_.can_be_constant = true; -} -void InpaintSimpleOperation::init_execution() -{ - cached_buffer_ = nullptr; - cached_buffer_ready_ = false; -} - -void InpaintSimpleOperation::deinit_execution() -{ - if (cached_buffer_) { - delete cached_buffer_; - cached_buffer_ = nullptr; - } - - cached_buffer_ready_ = false; -} - -void InpaintSimpleOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area = this->get_canvas(); -} - -void InpaintSimpleOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - MemoryBuffer *input = inputs[0]; - - if (input->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input->get_elem(0, 0)); - return; - } - - if (!cached_buffer_ready_) { - inpaint(input, output); - cached_buffer_ready_ = true; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h deleted file mode 100644 index be3c4aff53c..00000000000 --- a/source/blender/compositor/operations/COM_InpaintOperation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_array.hh" -#include "BLI_math_vector_types.hh" -#include "BLI_span.hh" - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -class InpaintSimpleOperation : public NodeOperation { - protected: - MemoryBuffer *cached_buffer_; - bool cached_buffer_ready_; - int max_distance_; - - public: - InpaintSimpleOperation(); - - void compute_inpainting_region(const MemoryBuffer *input, - const MemoryBuffer &inpainted_region, - const MemoryBuffer &distance_to_boundary, - MemoryBuffer *output); - - void fill_inpainting_region(const MemoryBuffer *input, - Span flooded_boundary, - MemoryBuffer &filled_region, - MemoryBuffer &distance_to_boundary_buffer, - MemoryBuffer &smoothing_radius_buffer); - - Array compute_inpainting_boundary(const MemoryBuffer *input); - - void inpaint(const MemoryBuffer *input, MemoryBuffer *output); - - void init_execution() override; - - void deinit_execution() override; - - void set_max_distance(int max_distance) - { - max_distance_ = max_distance; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_InvertOperation.cc b/source/blender/compositor/operations/COM_InvertOperation.cc deleted file mode 100644 index 40d70cddc90..00000000000 --- a/source/blender/compositor/operations/COM_InvertOperation.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_InvertOperation.h" - -namespace blender::compositor { - -InvertOperation::InvertOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - color_ = true; - alpha_ = false; - set_canvas_input_index(1); - flags_.can_be_constant = true; -} - -void InvertOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float value = *it.in(0); - const float inverted_value = 1.0f - value; - const float *color = it.in(1); - - if (color_) { - it.out[0] = (1.0f - color[0]) * value + color[0] * inverted_value; - it.out[1] = (1.0f - color[1]) * value + color[1] * inverted_value; - it.out[2] = (1.0f - color[2]) * value + color[2] * inverted_value; - } - else { - copy_v3_v3(it.out, color); - } - - if (alpha_) { - it.out[3] = (1.0f - color[3]) * value + color[3] * inverted_value; - } - else { - it.out[3] = color[3]; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h deleted file mode 100644 index c99ace2e2e7..00000000000 --- a/source/blender/compositor/operations/COM_InvertOperation.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class InvertOperation : public MultiThreadedOperation { - private: - bool alpha_; - bool color_; - - public: - InvertOperation(); - - void set_color(bool color) - { - color_ = color; - } - void set_alpha(bool alpha) - { - alpha_ = alpha; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc deleted file mode 100644 index 9ac991d1cff..00000000000 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingBlurOperation.h" - -namespace blender::compositor { - -KeyingBlurOperation::KeyingBlurOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - - size_ = 0; - axis_ = BLUR_AXIS_X; - - flags_.can_be_constant = true; -} - -void KeyingBlurOperation::get_area_of_interest(const int /*input_idx*/, - const rcti &output_area, - rcti &r_input_area) -{ - switch (axis_) { - case BLUR_AXIS_X: - r_input_area.xmin = output_area.xmin - size_; - r_input_area.ymin = output_area.ymin; - r_input_area.xmax = output_area.xmax + size_; - r_input_area.ymax = output_area.ymax; - break; - case BLUR_AXIS_Y: - r_input_area.xmin = output_area.xmin; - r_input_area.ymin = output_area.ymin - size_; - r_input_area.xmax = output_area.xmax; - r_input_area.ymax = output_area.ymax + size_; - break; - default: - BLI_assert_msg(0, "Unknown axis"); - break; - } -} - -void KeyingBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - BuffersIterator it = output->iterate_with(inputs, area); - - int coord_max; - int elem_stride; - std::function get_current_coord; - switch (axis_) { - case BLUR_AXIS_X: - get_current_coord = [&] { return it.x; }; - coord_max = this->get_width(); - elem_stride = input->elem_stride; - break; - case BLUR_AXIS_Y: - get_current_coord = [&] { return it.y; }; - coord_max = this->get_height(); - elem_stride = input->row_stride; - break; - } - - for (; !it.is_end(); ++it) { - const int coord = get_current_coord(); - const int start_coord = std::max(0, coord - size_ + 1); - const int end_coord = std::min(coord_max, coord + size_); - const int count = end_coord - start_coord; - - float sum = 0.0f; - const float *start = it.in(0) + (start_coord - coord) * elem_stride; - const float *end = start + count * elem_stride; - for (const float *elem = start; elem < end; elem += elem_stride) { - sum += *elem; - } - - *it.out = sum / count; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h deleted file mode 100644 index dd04d2b2a20..00000000000 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * Class with implementation of blurring for keying node - */ -class KeyingBlurOperation : public MultiThreadedOperation { - protected: - int size_; - int axis_; - - public: - enum BlurAxis { - BLUR_AXIS_X = 0, - BLUR_AXIS_Y = 1, - }; - - KeyingBlurOperation(); - - void set_size(int value) - { - size_ = value; - } - void set_axis(int value) - { - axis_ = value; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc deleted file mode 100644 index 55fb357a044..00000000000 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingClipOperation.h" - -namespace blender::compositor { - -KeyingClipOperation::KeyingClipOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - - kernel_radius_ = 3; - kernel_tolerance_ = 0.1f; - - clip_black_ = 0.0f; - clip_white_ = 1.0f; - - is_edge_matte_ = false; - - flags_.can_be_constant = true; -} - -void KeyingClipOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = output_area.xmin - kernel_radius_; - r_input_area.xmax = output_area.xmax + kernel_radius_; - r_input_area.ymin = output_area.ymin - kernel_radius_; - r_input_area.ymax = output_area.ymax + kernel_radius_; -} - -void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input = inputs[0]; - BuffersIterator it = output->iterate_with(inputs, area); - - const int delta = kernel_radius_; - const float tolerance = kernel_tolerance_; - const int width = this->get_width(); - const int height = this->get_height(); - const int row_stride = input->row_stride; - const int elem_stride = input->elem_stride; - for (; !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - - const int start_x = std::max(0, x - delta); - const int start_y = std::max(0, y - delta); - const int end_x = std::min(x + delta, width - 1); - const int end_y = std::min(y + delta, height - 1); - const int x_len = end_x - start_x + 1; - const int y_len = end_y - start_y + 1; - - const int total_count = x_len * y_len; - const int threshold_count = ceil(float(total_count) * 0.9f); - bool ok = false; - if (delta == 0) { - ok = true; - } - - const float *main_elem = it.in(0); - const float value = *main_elem; - const float *row = input->get_elem(start_x, start_y); - const float *end_row = row + y_len * row_stride; - int count = 0; - for (; ok == false && row < end_row; row += row_stride) { - const float *end_elem = row + x_len * elem_stride; - for (const float *elem = row; ok == false && elem < end_elem; elem += elem_stride) { - const float current_value = *elem; - if (fabsf(current_value - value) < tolerance) { - count++; - if (count >= threshold_count) { - ok = true; - } - } - } - } - - if (is_edge_matte_) { - *it.out = ok ? 0.0f : 1.0f; - } - else { - if (!ok) { - *it.out = value; - } - else if (value < clip_black_) { - *it.out = 0.0f; - } - else if (value >= clip_white_) { - *it.out = 1.0f; - } - else { - *it.out = (value - clip_black_) / (clip_white_ - clip_black_); - } - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h deleted file mode 100644 index f58a818a400..00000000000 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * Class with implementation of black/white clipping for keying node - */ -class KeyingClipOperation : public MultiThreadedOperation { - protected: - float clip_black_; - float clip_white_; - - int kernel_radius_; - float kernel_tolerance_; - - bool is_edge_matte_; - - public: - KeyingClipOperation(); - - void set_clip_black(float value) - { - clip_black_ = value; - } - void set_clip_white(float value) - { - clip_white_ = value; - } - - void set_kernel_radius(int value) - { - kernel_radius_ = value; - } - void set_kernel_tolerance(float value) - { - kernel_tolerance_ = value; - } - - void set_is_edge_matte(bool value) - { - is_edge_matte_ = value; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cc b/source/blender/compositor/operations/COM_KeyingDespillOperation.cc deleted file mode 100644 index 11534866362..00000000000 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_geom.h" - -#include "COM_KeyingDespillOperation.h" - -namespace blender::compositor { - -KeyingDespillOperation::KeyingDespillOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - despill_factor_ = 0.5f; - color_balance_ = 0.5f; - - flags_.can_be_constant = true; -} - -void KeyingDespillOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *pixel_color = it.in(0); - const float *screen_color = it.in(1); - - const int screen_primary_channel = max_axis_v3(screen_color); - const int other_1 = (screen_primary_channel + 1) % 3; - const int other_2 = (screen_primary_channel + 2) % 3; - - const int min_channel = std::min(other_1, other_2); - const int max_channel = std::max(other_1, other_2); - - const float average_value = color_balance_ * pixel_color[min_channel] + - (1.0f - color_balance_) * pixel_color[max_channel]; - const float amount = (pixel_color[screen_primary_channel] - average_value); - - copy_v4_v4(it.out, pixel_color); - - const float amount_despill = despill_factor_ * amount; - if (amount_despill > 0.0f) { - it.out[screen_primary_channel] = pixel_color[screen_primary_channel] - amount_despill; - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h deleted file mode 100644 index 16c4cf22a4a..00000000000 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * Class with implementation of keying despill node - */ -class KeyingDespillOperation : public MultiThreadedOperation { - protected: - float despill_factor_; - float color_balance_; - - public: - KeyingDespillOperation(); - - void set_despill_factor(float value) - { - despill_factor_ = value; - } - void set_color_balance(float value) - { - color_balance_ = value; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cc b/source/blender/compositor/operations/COM_KeyingOperation.cc deleted file mode 100644 index 8756c6070c4..00000000000 --- a/source/blender/compositor/operations/COM_KeyingOperation.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingOperation.h" - -#include "BLI_math_geom.h" - -namespace blender::compositor { - -static float get_pixel_saturation(const float pixel_color[4], - float screen_balance, - int primary_channel) -{ - const int other_1 = (primary_channel + 1) % 3; - const int other_2 = (primary_channel + 2) % 3; - - const int min_channel = std::min(other_1, other_2); - const int max_channel = std::max(other_1, other_2); - - const float val = pixel_color[max_channel] + - screen_balance * (pixel_color[min_channel] - pixel_color[max_channel]); - - return (pixel_color[primary_channel] - val) * fabsf(1.0f - val); -} - -KeyingOperation::KeyingOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Value); - - screen_balance_ = 0.5f; - - flags_.can_be_constant = true; -} - -void KeyingOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *pixel_color = it.in(0); - const float *screen_color = it.in(1); - - const int primary_channel = max_axis_v3(screen_color); - const float min_pixel_color = min_fff(pixel_color[0], pixel_color[1], pixel_color[2]); - - if (min_pixel_color > 1.0f) { - /* Overexposure doesn't happen on screen itself and usually happens - * on light sources in the shot, this need to be checked separately - * because saturation and falloff calculation is based on the fact - * that pixels are not overexposed. - */ - it.out[0] = 1.0f; - } - else { - const float saturation = get_pixel_saturation(pixel_color, screen_balance_, primary_channel); - const float screen_saturation = get_pixel_saturation( - screen_color, screen_balance_, primary_channel); - - if (saturation < 0) { - /* Means main channel of pixel is different from screen, - * assume this is completely a foreground. - */ - it.out[0] = 1.0f; - } - else if (saturation >= screen_saturation) { - /* Matched main channels and higher saturation on pixel - * is treated as completely background. - */ - it.out[0] = 0.0f; - } - else { - /* Nice alpha falloff on edges. */ - const float distance = 1.0f - saturation / screen_saturation; - it.out[0] = distance; - } - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h deleted file mode 100644 index 02f1a5dd54c..00000000000 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_MultiThreadedOperation.h" - -#include "BLI_listbase.h" - -namespace blender::compositor { - -/** - * Class with implementation of keying node - */ -class KeyingOperation : public MultiThreadedOperation { - protected: - float screen_balance_; - - public: - KeyingOperation(); - - void set_screen_balance(float value) - { - screen_balance_ = value; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc deleted file mode 100644 index 8966f084f1e..00000000000 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KeyingScreenOperation.h" - -#include "DNA_defaults.h" - -#include "BLI_array.hh" -#include "BLI_math_color.h" -#include "BLI_math_geom.h" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -#include "BKE_movieclip.h" -#include "BKE_tracking.h" - -#include "IMB_imbuf.hh" -#include "IMB_imbuf_types.hh" - -namespace blender::compositor { - -KeyingScreenOperation::KeyingScreenOperation() -{ - this->add_output_socket(DataType::Color); - movie_clip_ = nullptr; - framenumber_ = 0; - tracking_object_[0] = 0; - cached_marker_points_ = nullptr; -} - -void KeyingScreenOperation::init_execution() -{ - BLI_assert(cached_marker_points_ == nullptr); - if (movie_clip_) { - cached_marker_points_ = compute_marker_points(); - } -} - -void KeyingScreenOperation::deinit_execution() -{ - delete cached_marker_points_; - cached_marker_points_ = nullptr; -} - -Array *KeyingScreenOperation::compute_marker_points() -{ - MovieTracking *tracking = &movie_clip_->tracking; - - const MovieTrackingObject *tracking_object = nullptr; - if (tracking_object_[0]) { - tracking_object = BKE_tracking_object_get_named(tracking, tracking_object_); - if (!tracking_object) { - return nullptr; - } - } - else { - tracking_object = BKE_tracking_object_get_active(tracking); - } - BLI_assert(tracking_object != nullptr); - - int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, framenumber_); - - /* count sites */ - int sites_total = 0; - LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) { - const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame); - - if (marker->flag & MARKER_DISABLED) { - continue; - } - - float pos[2]; - add_v2_v2v2(pos, marker->pos, track->offset); - - if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) || !IN_RANGE_INCL(pos[1], 0.0f, 1.0f)) { - continue; - } - - sites_total++; - } - - if (!sites_total) { - return nullptr; - } - - MovieClipUser user = *DNA_struct_default_get(MovieClipUser); - BKE_movieclip_user_set_frame(&user, clip_frame); - ImBuf *ibuf = BKE_movieclip_get_ibuf(movie_clip_, &user); - - if (!ibuf) { - return nullptr; - } - - Array *marker_points = new Array(sites_total); - - int track_index = 0; - LISTBASE_FOREACH_INDEX (MovieTrackingTrack *, track, &tracking_object->tracks, track_index) { - const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame); - if (marker->flag & MARKER_DISABLED) { - continue; - } - - const float2 position = float2(marker->pos) + float2(track->offset); - - if (!IN_RANGE_INCL(position.x, 0.0f, 1.0f) || !IN_RANGE_INCL(position.y, 0.0f, 1.0f)) { - continue; - } - - ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, true, false); - - MarkerPoint &marker_point = (*marker_points)[track_index]; - marker_point.position = position; - - marker_point.color = float4(0.0f); - if (pattern_ibuf) { - for (int j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { - if (pattern_ibuf->float_buffer.data) { - marker_point.color += float4(&pattern_ibuf->float_buffer.data[4 * j]); - } - else { - uchar *rrgb = pattern_ibuf->byte_buffer.data; - marker_point.color += float4(srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f), - srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f), - srgb_to_linearrgb(float(rrgb[4 * j + 2]) / 255.0f), - srgb_to_linearrgb(float(rrgb[4 * j + 3]) / 255.0f)); - } - } - - marker_point.color /= pattern_ibuf->x * pattern_ibuf->y; - IMB_freeImBuf(pattern_ibuf); - } - } - - IMB_freeImBuf(ibuf); - - return marker_points; -} - -void KeyingScreenOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = COM_AREA_NONE; - - if (movie_clip_) { - MovieClipUser user = *DNA_struct_default_get(MovieClipUser); - int width, height; - int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, framenumber_); - - BKE_movieclip_user_set_frame(&user, clip_frame); - BKE_movieclip_get_size(movie_clip_, &user, &width, &height); - r_area = preferred_area; - r_area.xmax = r_area.xmin + width; - r_area.ymax = r_area.ymin + height; - } -} - -void KeyingScreenOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - if (!cached_marker_points_) { - output->fill(area, COM_COLOR_TRANSPARENT); - return; - } - - const int2 size = int2(this->get_width(), this->get_height()); - const float squared_shape_parameter = math::square(1.0f / smoothness_); - - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float2 normalized_pixel_location = float2(it.x, it.y) / float2(size); - - float4 weighted_sum = float4(0.0f); - float sum_of_weights = 0.0f; - for (const MarkerPoint &marker_point : *cached_marker_points_) { - const float2 difference = normalized_pixel_location - marker_point.position; - const float squared_distance = math::dot(difference, difference); - const float gaussian = math::exp(-squared_distance * squared_shape_parameter); - weighted_sum += marker_point.color * gaussian; - sum_of_weights += gaussian; - } - weighted_sum /= sum_of_weights; - - copy_v4_v4(it.out, weighted_sum); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h deleted file mode 100644 index f9d0484db40..00000000000 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_MultiThreadedOperation.h" - -#include "DNA_movieclip_types.h" - -#include "BLI_array.hh" -#include "BLI_listbase.h" -#include "BLI_math_base.hh" -#include "BLI_math_vector_types.hh" -#include "BLI_string.h" - -namespace blender::compositor { - -/** - * Class with implementation of green screen gradient rasterization - */ -class KeyingScreenOperation : public MultiThreadedOperation { - protected: - struct MarkerPoint { - float2 position; - float4 color; - }; - - MovieClip *movie_clip_; - float smoothness_; - int framenumber_; - Array *cached_marker_points_; - char tracking_object_[64]; - - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - Array *compute_marker_points(); - - public: - KeyingScreenOperation(); - - void init_execution() override; - void deinit_execution() override; - - void set_movie_clip(MovieClip *clip) - { - movie_clip_ = clip; - } - void set_tracking_object(const char *object) - { - BLI_strncpy(tracking_object_, object, sizeof(tracking_object_)); - } - void set_smoothness(float smoothness) - { - smoothness_ = math::interpolate(0.15f, 1.0f, smoothness); - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.cc b/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.cc deleted file mode 100644 index 4ce46c44687..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.cc +++ /dev/null @@ -1,325 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KuwaharaAnisotropicOperation.h" - -#include "BLI_math_base.h" -#include "BLI_math_base.hh" -#include "BLI_math_matrix_types.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -namespace blender::compositor { - -KuwaharaAnisotropicOperation::KuwaharaAnisotropicOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->flags_.can_be_constant = true; -} - -/* An implementation of the Anisotropic Kuwahara filter described in the paper: - * - * Kyprianidis, Jan Eric, Henry Kang, and Jurgen Dollner. "Image and video abstraction by - * anisotropic Kuwahara filtering." 2009. - * - * But with the polynomial weighting functions described in the paper: - * - * Kyprianidis, Jan Eric, et al. "Anisotropic Kuwahara Filtering with Polynomial Weighting - * Functions." 2010. - * - * And the sector weight function described in the paper: - * - * Kyprianidis, Jan Eric. "Image and video abstraction by multi-scale anisotropic Kuwahara - * filtering." 2011. - */ -void KuwaharaAnisotropicOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - using namespace math; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - /* The structure tensor is encoded in a float4 using a column major storage order, as can be - * seen in the KuwaharaAnisotropicStructureTensorOperation. */ - float4 encoded_structure_tensor = float4(inputs[2]->get_elem(it.x, it.y)); - float dxdx = encoded_structure_tensor.x; - float dxdy = encoded_structure_tensor.y; - float dydy = encoded_structure_tensor.w; - - /* Compute the first and second eigenvalues of the structure tensor using the equations in - * section "3.1 Orientation and Anisotropy Estimation" of the paper. */ - float eigenvalue_first_term = (dxdx + dydy) / 2.0f; - float eigenvalue_square_root_term = sqrt(square(dxdx - dydy) + 4.0f * square(dxdy)) / 2.0f; - float first_eigenvalue = eigenvalue_first_term + eigenvalue_square_root_term; - float second_eigenvalue = eigenvalue_first_term - eigenvalue_square_root_term; - - /* Compute the normalized eigenvector of the structure tensor oriented in direction of the - * minimum rate of change using the equations in section "3.1 Orientation and Anisotropy - * Estimation" of the paper. */ - float2 eigenvector = float2(first_eigenvalue - dxdx, -dxdy); - float eigenvector_length = length(eigenvector); - float2 unit_eigenvector = eigenvector_length != 0.0f ? eigenvector / eigenvector_length : - float2(1.0f); - - /* Compute the amount of anisotropy using equations in section "3.1 Orientation and Anisotropy - * Estimation" of the paper. The anisotropy ranges from 0 to 1, where 0 corresponds to - * isotropic and 1 corresponds to entirely anisotropic regions. */ - float eigenvalue_sum = first_eigenvalue + second_eigenvalue; - float eigenvalue_difference = first_eigenvalue - second_eigenvalue; - float anisotropy = eigenvalue_sum > 0.0f ? eigenvalue_difference / eigenvalue_sum : 0.0f; - - float radius = max(0.0f, *inputs[1]->get_elem(it.x, it.y)); - if (radius == 0) { - copy_v4_v4(it.out, inputs[0]->get_elem(it.x, it.y)); - continue; - } - - /* Compute the width and height of an ellipse that is more width-elongated for high anisotropy - * and more circular for low anisotropy, controlled using the eccentricity factor. Since the - * anisotropy is in the [0, 1] range, the width factor tends to 1 as the eccentricity tends to - * infinity and tends to infinity when the eccentricity tends to zero. This is based on the - * equations in section "3.2. Anisotropic Kuwahara Filtering" of the paper. */ - float ellipse_width_factor = (get_eccentricity() + anisotropy) / get_eccentricity(); - float ellipse_width = ellipse_width_factor * radius; - float ellipse_height = radius / ellipse_width_factor; - - /* Compute the cosine and sine of the angle that the eigenvector makes with the x axis. Since - * the eigenvector is normalized, its x and y components are the cosine and sine of the angle - * it makes with the x axis. */ - float cosine = unit_eigenvector.x; - float sine = unit_eigenvector.y; - - /* Compute an inverse transformation matrix that represents an ellipse of the given width and - * height and makes and an angle with the x axis of the given cosine and sine. This is an - * inverse matrix, so it transforms the ellipse into a disk of unit radius. */ - float2x2 inverse_ellipse_matrix = float2x2( - float2(cosine / ellipse_width, -sine / ellipse_height), - float2(sine / ellipse_width, cosine / ellipse_height)); - - /* Compute the bounding box of a zero centered ellipse whose major axis is aligned with the - * eigenvector and has the given width and height. This is based on the equations described in: - * - * https://iquilezles.org/articles/ellipses/ - * - * Notice that we only compute the upper bound, the lower bound is just negative that since the - * ellipse is zero centered. Also notice that we take the ceiling of the bounding box, just to - * ensure the filter window is at least 1x1. */ - float2 ellipse_major_axis = ellipse_width * unit_eigenvector; - float2 ellipse_minor_axis = ellipse_height * float2(unit_eigenvector.y, unit_eigenvector.x) * - float2(-1, 1); - int2 ellipse_bounds = int2( - ceil(sqrt(square(ellipse_major_axis) + square(ellipse_minor_axis)))); - - /* Compute the overlap polynomial parameters for 8-sector ellipse based on the equations in - * section "3 Alternative Weighting Functions" of the polynomial weights paper. More on this - * later in the code. */ - int number_of_sectors = 8; - float sector_center_overlap_parameter = 2.0f / radius; - float sector_envelope_angle = ((3.0f / 2.0f) * M_PI) / number_of_sectors; - float cross_sector_overlap_parameter = (sector_center_overlap_parameter + - cos(sector_envelope_angle)) / - square(sin(sector_envelope_angle)); - - /* We need to compute the weighted mean of color and squared color of each of the 8 sectors of - * the ellipse, so we declare arrays for accumulating those and initialize them in the next - * code section. */ - float4 weighted_mean_of_squared_color_of_sectors[8]; - float4 weighted_mean_of_color_of_sectors[8]; - float sum_of_weights_of_sectors[8]; - - /* The center pixel (0, 0) is exempt from the main loop below for reasons that are explained in - * the first if statement in the loop, so we need to accumulate its color, squared color, and - * weight separately first. Luckily, the zero coordinates of the center pixel zeros out most of - * the complex computations below, and it can easily be shown that the weight for the center - * pixel in all sectors is simply (1 / number_of_sectors). */ - float4 center_color = float4(inputs[0]->get_elem(it.x, it.y)); - float4 center_color_squared = center_color * center_color; - float center_weight = 1.0f / number_of_sectors; - float4 weighted_center_color = center_color * center_weight; - float4 weighted_center_color_squared = center_color_squared * center_weight; - for (int i = 0; i < number_of_sectors; i++) { - weighted_mean_of_squared_color_of_sectors[i] = weighted_center_color_squared; - weighted_mean_of_color_of_sectors[i] = weighted_center_color; - sum_of_weights_of_sectors[i] = center_weight; - } - - /* Loop over the window of pixels inside the bounding box of the ellipse. However, we utilize - * the fact that ellipses are mirror symmetric along the horizontal axis, so we reduce the - * window to only the upper two quadrants, and compute each two mirrored pixels at the same - * time using the same weight as an optimization. */ - for (int j = 0; j <= ellipse_bounds.y; j++) { - for (int i = -ellipse_bounds.x; i <= ellipse_bounds.x; i++) { - /* Since we compute each two mirrored pixels at the same time, we need to also exempt the - * pixels whose x coordinates are negative and their y coordinates are zero, that's because - * those are mirrored versions of the pixels whose x coordinates are positive and their y - * coordinates are zero, and we don't want to compute and accumulate them twice. Moreover, - * we also need to exempt the center pixel with zero coordinates for the same reason, - * however, since the mirror of the center pixel is itself, it need to be accumulated - * separately, hence why we did that in the code section just before this loop. */ - if (j == 0 && i <= 0) { - continue; - } - - /* Map the pixels of the ellipse into a unit disk, exempting any points that are not part - * of the ellipse or disk. */ - float2 disk_point = inverse_ellipse_matrix * float2(i, j); - float disk_point_length_squared = dot(disk_point, disk_point); - if (disk_point_length_squared > 1.0f) { - continue; - } - - /* While each pixel belongs to a single sector in the ellipse, we expand the definition of - * a sector a bit to also overlap with other sectors as illustrated in Figure 8 of the - * polynomial weights paper. So each pixel may contribute to multiple sectors, and thus we - * compute its weight in each of the 8 sectors. */ - float sector_weights[8]; - - /* We evaluate the weighting polynomial at each of the 8 sectors by rotating the disk point - * by 45 degrees and evaluating the weighting polynomial at each incremental rotation. To - * avoid potentially expensive rotations, we utilize the fact that rotations by 90 degrees - * are simply swapping of the coordinates and negating the x component. We also note that - * since the y term of the weighting polynomial is squared, it is not affected by the sign - * and can be computed once for the x and once for the y coordinates. So we compute every - * other even-indexed 4 weights by successive 90 degree rotations as discussed. */ - float2 polynomial = sector_center_overlap_parameter - - cross_sector_overlap_parameter * square(disk_point); - sector_weights[0] = square(max(0.0f, disk_point.y + polynomial.x)); - sector_weights[2] = square(max(0.0f, -disk_point.x + polynomial.y)); - sector_weights[4] = square(max(0.0f, -disk_point.y + polynomial.x)); - sector_weights[6] = square(max(0.0f, disk_point.x + polynomial.y)); - - /* Then we rotate the disk point by 45 degrees, which is a simple expression involving a - * constant as can be demonstrated by applying a 45 degree rotation matrix. */ - float2 rotated_disk_point = M_SQRT1_2 * float2(disk_point.x - disk_point.y, - disk_point.x + disk_point.y); - - /* Finally, we compute every other odd-index 4 weights starting from the 45 degree rotated - * disk point. */ - float2 rotated_polynomial = sector_center_overlap_parameter - - cross_sector_overlap_parameter * square(rotated_disk_point); - sector_weights[1] = square(max(0.0f, rotated_disk_point.y + rotated_polynomial.x)); - sector_weights[3] = square(max(0.0f, -rotated_disk_point.x + rotated_polynomial.y)); - sector_weights[5] = square(max(0.0f, -rotated_disk_point.y + rotated_polynomial.x)); - sector_weights[7] = square(max(0.0f, rotated_disk_point.x + rotated_polynomial.y)); - - /* We compute a radial Gaussian weighting component such that pixels further away from the - * sector center gets attenuated, and we also divide by the sum of sector weights to - * normalize them, since the radial weight will eventually be multiplied to the sector - * weight below. */ - float sector_weights_sum = sector_weights[0] + sector_weights[1] + sector_weights[2] + - sector_weights[3] + sector_weights[4] + sector_weights[5] + - sector_weights[6] + sector_weights[7]; - float radial_gaussian_weight = exp(-M_PI * disk_point_length_squared) / sector_weights_sum; - - /* Load the color of the pixel and its mirrored pixel and compute their square. */ - float4 upper_color = float4( - inputs[0]->get_elem(clamp(it.x + i, 0, inputs[0]->get_width() - 1), - clamp(it.y + j, 0, inputs[0]->get_height() - 1))); - float4 lower_color = float4( - inputs[0]->get_elem(clamp(it.x - i, 0, inputs[0]->get_width() - 1), - clamp(it.y - j, 0, inputs[0]->get_height() - 1))); - float4 upper_color_squared = upper_color * upper_color; - float4 lower_color_squared = lower_color * lower_color; - - for (int k = 0; k < number_of_sectors; k++) { - float weight = sector_weights[k] * radial_gaussian_weight; - - /* Accumulate the pixel to each of the sectors multiplied by the sector weight. */ - int upper_index = k; - sum_of_weights_of_sectors[upper_index] += weight; - weighted_mean_of_color_of_sectors[upper_index] += upper_color * weight; - weighted_mean_of_squared_color_of_sectors[upper_index] += upper_color_squared * weight; - - /* Accumulate the mirrored pixel to each of the sectors multiplied by the sector weight. - */ - int lower_index = (k + number_of_sectors / 2) % number_of_sectors; - sum_of_weights_of_sectors[lower_index] += weight; - weighted_mean_of_color_of_sectors[lower_index] += lower_color * weight; - weighted_mean_of_squared_color_of_sectors[lower_index] += lower_color_squared * weight; - } - } - } - - /* Compute the weighted sum of mean of sectors, such that sectors with lower standard deviation - * gets more significant weight than sectors with higher standard deviation. */ - float sum_of_weights = 0.0f; - float4 weighted_sum = float4(0.0f); - for (int i = 0; i < number_of_sectors; i++) { - weighted_mean_of_color_of_sectors[i] /= sum_of_weights_of_sectors[i]; - weighted_mean_of_squared_color_of_sectors[i] /= sum_of_weights_of_sectors[i]; - - float4 color_mean = weighted_mean_of_color_of_sectors[i]; - float4 squared_color_mean = weighted_mean_of_squared_color_of_sectors[i]; - float4 color_variance = abs(squared_color_mean - color_mean * color_mean); - - float standard_deviation = dot(sqrt(color_variance.xyz()), float3(1.0)); - - /* Compute the sector weight based on the weight function introduced in section "3.3.1 - * Single-scale Filtering" of the multi-scale paper. Use a threshold of 0.02 to avoid zero - * division and avoid artifacts in homogeneous regions as demonstrated in the paper. */ - float weight = 1.0f / pow(max(0.02f, standard_deviation), get_sharpness()); - - sum_of_weights += weight; - weighted_sum += color_mean * weight; - } - - /* Fallback to the original color if all sector weights are zero due to very high standard - * deviation and sharpness. */ - if (sum_of_weights == 0.0f) { - weighted_sum = center_color; - } - else { - weighted_sum /= sum_of_weights; - } - - copy_v4_v4(it.out, weighted_sum); - } -} - -/* The sharpness controls the sharpness of the transitions between the kuwahara sectors, which is - * controlled by the weighting function pow(standard_deviation, -sharpness) as can be seen in the - * compute function. The transition is completely smooth when the sharpness is zero and completely - * sharp when it is infinity. But realistically, the sharpness doesn't change much beyond the value - * of 16 due to its exponential nature, so we just assume a maximum sharpness of 16. - * - * The stored sharpness is in the range [0, 1], so we multiply by 16 to get it in the range - * [0, 16], however, we also square it before multiplication to slow down the rate of change near - * zero to counter its exponential nature for more intuitive user control. */ -float KuwaharaAnisotropicOperation::get_sharpness() -{ - return sharpness_ * sharpness_ * 16.0f; -} - -/* The eccentricity controls how much the image anisotropy affects the eccentricity of the - * kuwahara sectors, which is controlled by the following factor that gets multiplied to the - * radius to get the ellipse width and divides the radius to get the ellipse height: - * - * (eccentricity + anisotropy) / eccentricity - * - * Since the anisotropy is in the [0, 1] range, the factor tends to 1 as the eccentricity tends - * to infinity and tends to infinity when the eccentricity tends to zero. The stored eccentricity - * is in the range [0, 2], we map that to the range [infinity, 0.5] by taking the reciprocal, - * satisfying the aforementioned limits. The upper limit doubles the computed default - * eccentricity, which users can use to enhance the directionality of the filter. Instead of - * actual infinity, we just use an eccentricity of 1 / 0.01 since the result is very similar to - * that of infinity. */ -float KuwaharaAnisotropicOperation::get_eccentricity() -{ - return 1.0f / math::max(0.01f, eccentricity_); -} - -void KuwaharaAnisotropicOperation::set_sharpness(float sharpness) -{ - sharpness_ = sharpness; -} - -void KuwaharaAnisotropicOperation::set_eccentricity(float eccentricity) -{ - eccentricity_ = eccentricity; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.h b/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.h deleted file mode 100644 index 5b52032975a..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicOperation.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "DNA_node_types.h" - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class KuwaharaAnisotropicOperation : public MultiThreadedOperation { - public: - float sharpness_; - float eccentricity_; - - KuwaharaAnisotropicOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - float get_sharpness(); - float get_eccentricity(); - void set_sharpness(float sharpness); - void set_eccentricity(float eccentricity); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc deleted file mode 100644 index 665bac0e26a..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_KuwaharaAnisotropicStructureTensorOperation.h" - -#include "BLI_math_base.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -namespace blender::compositor { - -KuwaharaAnisotropicStructureTensorOperation::KuwaharaAnisotropicStructureTensorOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->flags_.can_be_constant = true; -} - -/* Computes the structure tensor of the image using a Dirac delta window function as described in - * section "3.2 Local Structure Estimation" of the paper: - * - * Kyprianidis, Jan Eric. "Image and video abstraction by multi-scale anisotropic Kuwahara - * filtering." 2011. - * - * The structure tensor should then be smoothed using a Gaussian function to eliminate high - * frequency details. */ -void KuwaharaAnisotropicStructureTensorOperation::update_memory_buffer_partial( - MemoryBuffer *output, const rcti &area, Span inputs) -{ - using math::max, math::min, math::dot; - MemoryBuffer *image = inputs[0]; - const int width = image->get_width(); - const int height = image->get_height(); - - /* The weight kernels of the filter optimized for rotational symmetry described in section - * "3.2.1 Gradient Calculation". */ - const float corner_weight = 0.182f; - const float center_weight = 1.0f - 2.0f * corner_weight; - - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - - float3 input_color; - float3 x_partial_derivative = float3(0.0f); - input_color = float3(image->get_elem(max(0, x - 1), min(height - 1, y + 1))); - x_partial_derivative += input_color * -corner_weight; - input_color = float3(image->get_elem(max(0, x - 1), y)); - x_partial_derivative += input_color * -center_weight; - input_color = float3(image->get_elem(max(0, x - 1), max(0, y - 1))); - x_partial_derivative += input_color * -corner_weight; - input_color = float3(image->get_elem(min(width - 1, x + 1), min(height - 1, y + 1))); - x_partial_derivative += input_color * corner_weight; - input_color = float3(image->get_elem(min(width - 1, x + 1), y)); - x_partial_derivative += input_color * center_weight; - input_color = float3(image->get_elem(min(width - 1, x + 1), max(0, y - 1))); - x_partial_derivative += input_color * corner_weight; - - float3 y_partial_derivative = float3(0.0f); - input_color = float3(image->get_elem(max(0, x - 1), min(height - 1, y + 1))); - y_partial_derivative += input_color * corner_weight; - input_color = float3(image->get_elem(x, min(height - 1, y + 1))); - y_partial_derivative += input_color * center_weight; - input_color = float3(image->get_elem(min(width - 1, x + 1), min(height - 1, y + 1))); - y_partial_derivative += input_color * corner_weight; - input_color = float3(image->get_elem(max(0, x - 1), max(0, y - 1))); - y_partial_derivative += input_color * -corner_weight; - input_color = float3(image->get_elem(x, max(0, y - 1))); - y_partial_derivative += input_color * -center_weight; - input_color = float3(image->get_elem(min(width - 1, x + 1), max(0, y - 1))); - y_partial_derivative += input_color * -corner_weight; - - /* We encode the structure tensor in a float4 using a column major storage order. */ - float4 structure_tensor = float4(dot(x_partial_derivative, x_partial_derivative), - dot(x_partial_derivative, y_partial_derivative), - dot(x_partial_derivative, y_partial_derivative), - dot(y_partial_derivative, y_partial_derivative)); - copy_v4_v4(it.out, structure_tensor); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h deleted file mode 100644 index 5a8f6069e10..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class KuwaharaAnisotropicStructureTensorOperation : public MultiThreadedOperation { - public: - KuwaharaAnisotropicStructureTensorOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaClassicOperation.cc b/source/blender/compositor/operations/COM_KuwaharaClassicOperation.cc deleted file mode 100644 index 9dee9642ae9..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaClassicOperation.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_base.hh" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -#include "COM_KuwaharaClassicOperation.h" -#include "COM_SummedAreaTableOperation.h" - -namespace blender::compositor { - -KuwaharaClassicOperation::KuwaharaClassicOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - this->flags_.can_be_constant = true; -} - -void KuwaharaClassicOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *image = inputs[0]; - if (image->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), image->get_elem(0, 0)); - return; - } - MemoryBuffer *size_image = inputs[1]; - MemoryBuffer *sat = inputs[2]; - MemoryBuffer *sat_squared = inputs[3]; - - int width = image->get_width(); - int height = image->get_height(); - - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int x = it.x; - const int y = it.y; - - float4 mean_of_color[4] = {float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f)}; - float4 mean_of_squared_color[4] = {float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f)}; - int quadrant_pixel_count[4] = {0, 0, 0, 0}; - - const float size = *size_image->get_elem(x, y); - const int kernel_size = int(math::max(0.0f, size)); - - /* For high radii, we accelerate the filter using a summed area table, making the filter - * execute in constant time as opposed to having quadratic complexity. Except if high precision - * is enabled, since summed area tables are less precise. */ - if (!high_precision_ && size > 5.0f) { - for (int q = 0; q < 4; q++) { - /* A fancy expression to compute the sign of the quadrant q. */ - int2 sign = int2((q % 2) * 2 - 1, ((q / 2) * 2 - 1)); - - int2 lower_bound = int2(x, y) - - int2(sign.x > 0 ? 0 : kernel_size, sign.y > 0 ? 0 : kernel_size); - int2 upper_bound = int2(x, y) + - int2(sign.x < 0 ? 0 : kernel_size, sign.y < 0 ? 0 : kernel_size); - - /* Limit the quadrants to the image bounds. */ - int2 image_bound = int2(width, height) - int2(1); - int2 corrected_lower_bound = math::min(image_bound, math::max(int2(0, 0), lower_bound)); - int2 corrected_upper_bound = math::min(image_bound, math::max(int2(0, 0), upper_bound)); - int2 region_size = corrected_upper_bound - corrected_lower_bound + int2(1, 1); - quadrant_pixel_count[q] = region_size.x * region_size.y; - - rcti kernel_area; - kernel_area.xmin = corrected_lower_bound[0]; - kernel_area.ymin = corrected_lower_bound[1]; - kernel_area.xmax = corrected_upper_bound[0]; - kernel_area.ymax = corrected_upper_bound[1]; - - mean_of_color[q] = summed_area_table_sum(sat, kernel_area); - mean_of_squared_color[q] = summed_area_table_sum(sat_squared, kernel_area); - } - } - else { - /* Split surroundings of pixel into 4 overlapping regions. */ - for (int dy = -kernel_size; dy <= kernel_size; dy++) { - for (int dx = -kernel_size; dx <= kernel_size; dx++) { - - int xx = x + dx; - int yy = y + dy; - if (xx < 0 || yy < 0 || xx >= image->get_width() || yy >= image->get_height()) { - continue; - } - - float4 color; - image->read_elem(xx, yy, &color.x); - - if (dx >= 0 && dy >= 0) { - const int quadrant_index = 0; - mean_of_color[quadrant_index] += color; - mean_of_squared_color[quadrant_index] += color * color; - quadrant_pixel_count[quadrant_index]++; - } - - if (dx <= 0 && dy >= 0) { - const int quadrant_index = 1; - mean_of_color[quadrant_index] += color; - mean_of_squared_color[quadrant_index] += color * color; - quadrant_pixel_count[quadrant_index]++; - } - - if (dx <= 0 && dy <= 0) { - const int quadrant_index = 2; - mean_of_color[quadrant_index] += color; - mean_of_squared_color[quadrant_index] += color * color; - quadrant_pixel_count[quadrant_index]++; - } - - if (dx >= 0 && dy <= 0) { - const int quadrant_index = 3; - mean_of_color[quadrant_index] += color; - mean_of_squared_color[quadrant_index] += color * color; - quadrant_pixel_count[quadrant_index]++; - } - } - } - } - - /* Choose the region with lowest variance. */ - float min_var = FLT_MAX; - int min_index = 0; - for (int i = 0; i < 4; i++) { - mean_of_color[i] /= quadrant_pixel_count[i]; - mean_of_squared_color[i] /= quadrant_pixel_count[i]; - float4 color_variance = mean_of_squared_color[i] - mean_of_color[i] * mean_of_color[i]; - - float variance = math::dot(color_variance.xyz(), float3(1.0f)); - if (variance < min_var) { - min_var = variance; - min_index = i; - } - } - - it.out[0] = mean_of_color[min_index].x; - it.out[1] = mean_of_color[min_index].y; - it.out[2] = mean_of_color[min_index].z; - it.out[3] = mean_of_color[min_index].w; /* Also apply filter to alpha channel. */ - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_KuwaharaClassicOperation.h b/source/blender/compositor/operations/COM_KuwaharaClassicOperation.h deleted file mode 100644 index fb57c6990a7..00000000000 --- a/source/blender/compositor/operations/COM_KuwaharaClassicOperation.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class KuwaharaClassicOperation : public MultiThreadedOperation { - bool high_precision_; - - public: - KuwaharaClassicOperation(); - - void set_high_precision(bool high_precision) - { - high_precision_ = high_precision; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cc b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cc deleted file mode 100644 index bb84cd6c3b6..00000000000 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_LuminanceMatteOperation.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -LuminanceMatteOperation::LuminanceMatteOperation() -{ - add_input_socket(DataType::Color); - add_output_socket(DataType::Value); - - flags_.can_be_constant = true; -} - -void LuminanceMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - const float luminance = IMB_colormanagement_get_luminance(color); - - /* One line thread-friend algorithm: - * `it.out[0] = std::min(color[3], std::min(1.0f, std::max(0.0f, ((luminance - low) / (high - - * low))));` - */ - - /* Test range. */ - const float high = settings_->t1; - const float low = settings_->t2; - float alpha; - if (luminance > high) { - alpha = 1.0f; - } - else if (luminance < low) { - alpha = 0.0f; - } - else { /* Blend. */ - alpha = (luminance - low) / (high - low); - } - - /* Store matte(alpha) value in [0] to go with - * COM_SetAlphaMultiplyOperation and the Value output. - */ - - /* Don't make something that was more transparent less transparent. */ - it.out[0] = std::min(alpha, color[3]); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h deleted file mode 100644 index 31e56c2448b..00000000000 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class LuminanceMatteOperation : public MultiThreadedOperation { - private: - NodeChroma *settings_; - - public: - /** - * Default constructor - */ - LuminanceMatteOperation(); - - void set_settings(NodeChroma *node_chroma) - { - settings_ = node_chroma; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cc b/source/blender/compositor/operations/COM_MapRangeOperation.cc deleted file mode 100644 index 781df2ca46c..00000000000 --- a/source/blender/compositor/operations/COM_MapRangeOperation.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapRangeOperation.h" - -namespace blender::compositor { - -MapRangeOperation::MapRangeOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - use_clamp_ = false; - flags_.can_be_constant = true; -} - -/* The code below assumes all data is inside range +- this, and that input buffer is single channel - */ -#define BLENDER_ZMAX 10000.0f - -void MapRangeOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float source_min = *it.in(1); - const float source_max = *it.in(2); - if (fabsf(source_max - source_min) < 1e-6f) { - it.out[0] = 0.0f; - continue; - } - - float value = *it.in(0); - const float dest_min = *it.in(3); - const float dest_max = *it.in(4); - if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) { - value = (value - source_min) / (source_max - source_min); - value = dest_min + value * (dest_max - dest_min); - } - else if (value > BLENDER_ZMAX) { - value = dest_max; - } - else { - value = dest_min; - } - - if (use_clamp_) { - if (dest_max > dest_min) { - CLAMP(value, dest_min, dest_max); - } - else { - CLAMP(value, dest_max, dest_min); - } - } - - it.out[0] = value; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h deleted file mode 100644 index c4dfb823233..00000000000 --- a/source/blender/compositor/operations/COM_MapRangeOperation.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_texture_types.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class MapRangeOperation : public MultiThreadedOperation { - private: - bool use_clamp_; - - public: - /** - * Default constructor - */ - MapRangeOperation(); - - /** - * Clamp the output - */ - void set_use_clamp(bool value) - { - use_clamp_ = value; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cc b/source/blender/compositor/operations/COM_MapUVOperation.cc deleted file mode 100644 index d3cbe0a52e9..00000000000 --- a/source/blender/compositor/operations/COM_MapUVOperation.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapUVOperation.h" - -namespace blender::compositor { - -MapUVOperation::MapUVOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_input_socket(DataType::Vector); - this->add_output_socket(DataType::Color); - alpha_ = 0.0f; - nearest_neighbour_ = false; - flags_.can_be_constant = true; - set_canvas_input_index(UV_INPUT_INDEX); -} - -void MapUVOperation::init_data() -{ - NodeOperation *image_input = get_input_operation(IMAGE_INPUT_INDEX); - image_width_ = image_input->get_width(); - image_height_ = image_input->get_height(); - - NodeOperation *uv_input = get_input_operation(UV_INPUT_INDEX); - uv_width_ = uv_input->get_width(); - uv_height_ = uv_input->get_height(); -} - -bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_alpha) -{ - if (x < 0.0f || x >= uv_width_ || y < 0.0f || y >= uv_height_) { - r_u = 0.0f; - r_v = 0.0f; - r_alpha = 0.0f; - return false; - } - - float vector[3]; - uv_input_read_fn_(x, y, vector); - r_u = vector[0] * image_width_; - r_v = vector[1] * image_height_; - r_alpha = vector[2]; - return true; -} - -void MapUVOperation::pixel_transform(const float xy[2], - float r_uv[2], - float r_deriv[2][2], - float &r_alpha) -{ - float uv[2], alpha; /* temporary variables for derivative estimation */ - int num; - - read_uv(xy[0], xy[1], r_uv[0], r_uv[1], r_alpha); - - /* Estimate partial derivatives using 1-pixel offsets */ - const float epsilon[2] = {1.0f, 1.0f}; - - zero_v2(r_deriv[0]); - zero_v2(r_deriv[1]); - - num = 0; - if (read_uv(xy[0] + epsilon[0], xy[1], uv[0], uv[1], alpha)) { - r_deriv[0][0] += uv[0] - r_uv[0]; - r_deriv[1][0] += uv[1] - r_uv[1]; - num++; - } - if (read_uv(xy[0] - epsilon[0], xy[1], uv[0], uv[1], alpha)) { - r_deriv[0][0] += r_uv[0] - uv[0]; - r_deriv[1][0] += r_uv[1] - uv[1]; - num++; - } - if (num > 0) { - float numinv = 1.0f / float(num); - r_deriv[0][0] *= numinv; - r_deriv[1][0] *= numinv; - } - - num = 0; - if (read_uv(xy[0], xy[1] + epsilon[1], uv[0], uv[1], alpha)) { - r_deriv[0][1] += uv[0] - r_uv[0]; - r_deriv[1][1] += uv[1] - r_uv[1]; - num++; - } - if (read_uv(xy[0], xy[1] - epsilon[1], uv[0], uv[1], alpha)) { - r_deriv[0][1] += r_uv[0] - uv[0]; - r_deriv[1][1] += r_uv[1] - uv[1]; - num++; - } - if (num > 0) { - float numinv = 1.0f / float(num); - r_deriv[0][1] *= numinv; - r_deriv[1][1] *= numinv; - } -} - -void MapUVOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: { - r_input_area = get_input_operation(IMAGE_INPUT_INDEX)->get_canvas(); - break; - } - case UV_INPUT_INDEX: { - r_input_area = output_area; - expand_area_for_sampler(r_input_area, PixelSampler::Bilinear); - break; - } - } -} - -void MapUVOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span inputs) -{ - const MemoryBuffer *uv_input = inputs[UV_INPUT_INDEX]; - uv_input_read_fn_ = [=](float x, float y, float *out) { - uv_input->read_elem_bilinear(x, y, out); - }; -} - -void MapUVOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_image = inputs[IMAGE_INPUT_INDEX]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float xy[2] = {float(it.x), float(it.y)}; - float uv[2]; - float deriv[2][2]; - float alpha; - pixel_transform(xy, uv, deriv, alpha); - if (alpha == 0.0f) { - zero_v4(it.out); - continue; - } - - if (nearest_neighbour_) { - input_image->read_elem_sampled(uv[0], uv[1], PixelSampler::Nearest, it.out); - } - else { - /* EWA filtering. */ - input_image->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], false, it.out); - - /* UV to alpha threshold. */ - const float threshold = alpha_ * 0.05f; - /* XXX alpha threshold is used to fade out pixels on boundaries with invalid derivatives. - * this calculation is not very well defined, should be looked into if it becomes a problem - * ... - */ - const float du = len_v2(deriv[0]); - const float dv = len_v2(deriv[1]); - const float factor = 1.0f - threshold * (du / image_width_ + dv / image_height_); - if (factor < 0.0f) { - alpha = 0.0f; - } - else { - alpha *= factor; - } - } - /* "pre-multiplied" */ - if (alpha < 1.0f) { - mul_v4_fl(it.out, alpha); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h deleted file mode 100644 index ca86af65407..00000000000 --- a/source/blender/compositor/operations/COM_MapUVOperation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class MapUVOperation : public MultiThreadedOperation { - private: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int UV_INPUT_INDEX = 1; - - int uv_width_; - int uv_height_; - int image_width_; - int image_height_; - - float alpha_; - bool nearest_neighbour_; - std::function uv_input_read_fn_; - - public: - MapUVOperation(); - - void pixel_transform(const float xy[2], float r_uv[2], float r_deriv[2][2], float &r_alpha); - - void init_data() override; - - void set_alpha(float alpha) - { - alpha_ = alpha; - } - - void set_nearest_neighbour(bool nearest_neighbour) - { - nearest_neighbour_ = nearest_neighbour; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - bool read_uv(float x, float y, float &r_u, float &r_v, float &r_alpha); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapValueOperation.cc b/source/blender/compositor/operations/COM_MapValueOperation.cc deleted file mode 100644 index cb385711baa..00000000000 --- a/source/blender/compositor/operations/COM_MapValueOperation.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MapValueOperation.h" - -namespace blender::compositor { - -MapValueOperation::MapValueOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - flags_.can_be_constant = true; -} - -void MapValueOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float input = *it.in(0); - const TexMapping *texmap = settings_; - float value = (input + texmap->loc[0]) * texmap->size[0]; - if (texmap->flag & TEXMAP_CLIP_MIN) { - if (value < texmap->min[0]) { - value = texmap->min[0]; - } - } - if (texmap->flag & TEXMAP_CLIP_MAX) { - if (value > texmap->max[0]) { - value = texmap->max[0]; - } - } - - it.out[0] = value; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h deleted file mode 100644 index 26ed2ed466d..00000000000 --- a/source/blender/compositor/operations/COM_MapValueOperation.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_texture_types.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class MapValueOperation : public MultiThreadedOperation { - private: - const TexMapping *settings_; - - public: - MapValueOperation(); - - /** - * \brief set the TexMapping settings - */ - void set_settings(const TexMapping *settings) - { - settings_ = settings; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MaskOperation.cc b/source/blender/compositor/operations/COM_MaskOperation.cc deleted file mode 100644 index 545ef9e8936..00000000000 --- a/source/blender/compositor/operations/COM_MaskOperation.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MaskOperation.h" - -#include "BKE_lib_id.hh" -#include "BKE_mask.h" - -namespace blender::compositor { - -MaskOperation::MaskOperation() -{ - this->add_output_socket(DataType::Value); - mask_ = nullptr; - mask_width_ = 0; - mask_height_ = 0; - mask_width_inv_ = 0.0f; - mask_height_inv_ = 0.0f; - frame_shutter_ = 0.0f; - frame_number_ = 0; - raster_mask_handle_tot_ = 1; - memset(raster_mask_handles_, 0, sizeof(raster_mask_handles_)); -} - -void MaskOperation::init_execution() -{ - if (mask_ && raster_mask_handles_[0] == nullptr) { - if (raster_mask_handle_tot_ == 1) { - raster_mask_handles_[0] = BKE_maskrasterize_handle_new(); - - BKE_maskrasterize_handle_init( - raster_mask_handles_[0], mask_, mask_width_, mask_height_, true, true, do_feather_); - } - else { - /* make a throw away copy of the mask */ - const float frame = float(frame_number_) - frame_shutter_; - const float frame_step = (frame_shutter_ * 2.0f) / raster_mask_handle_tot_; - float frame_iter = frame; - - Mask *mask_temp = (Mask *)BKE_id_copy_ex( - nullptr, &mask_->id, nullptr, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA); - - /* trick so we can get unkeyed edits to display */ - { - LISTBASE_FOREACH (MaskLayer *, masklay, &mask_temp->masklayers) { - MaskLayerShape *masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, - frame_number_); - BKE_mask_layer_shape_from_mask(masklay, masklay_shape); - } - } - - for (uint i = 0; i < raster_mask_handle_tot_; i++) { - raster_mask_handles_[i] = BKE_maskrasterize_handle_new(); - - /* re-eval frame info */ - BKE_mask_evaluate(mask_temp, frame_iter, true); - - BKE_maskrasterize_handle_init(raster_mask_handles_[i], - mask_temp, - mask_width_, - mask_height_, - true, - true, - do_feather_); - - frame_iter += frame_step; - } - - BKE_id_free(nullptr, &mask_temp->id); - } - } -} - -void MaskOperation::deinit_execution() -{ - for (uint i = 0; i < raster_mask_handle_tot_; i++) { - if (raster_mask_handles_[i]) { - BKE_maskrasterize_handle_free(raster_mask_handles_[i]); - raster_mask_handles_[i] = nullptr; - } - } -} - -void MaskOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - if (!mask_ || mask_width_ == 0 || mask_height_ == 0) { - r_area = COM_AREA_NONE; - } - else { - r_area = preferred_area; - r_area.xmax = r_area.xmin + mask_width_; - r_area.ymax = r_area.ymin + mask_height_; - } -} - -void MaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - Vector handles = get_non_null_handles(); - if (handles.is_empty()) { - output->fill(area, COM_VALUE_ZERO); - return; - } - - float xy[2]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - xy[0] = it.x * mask_width_inv_ + mask_px_ofs_[0]; - xy[1] = it.y * mask_height_inv_ + mask_px_ofs_[1]; - *it.out = 0.0f; - for (MaskRasterHandle *handle : handles) { - *it.out += BKE_maskrasterize_handle_sample(handle, xy); - } - - /* Until we get better falloff. */ - *it.out /= raster_mask_handle_tot_; - } -} - -Vector MaskOperation::get_non_null_handles() const -{ - Vector handles; - for (int i = 0; i < raster_mask_handle_tot_; i++) { - MaskRasterHandle *handle = raster_mask_handles_[i]; - if (handle == nullptr) { - continue; - } - handles.append(handle); - } - return handles; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h deleted file mode 100644 index b79766ec53c..00000000000 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ /dev/null @@ -1,101 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_listbase.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_mask_types.h" -#include "IMB_imbuf_types.hh" - -/* Forward declarations. */ -struct MaskRasterHandle; - -namespace blender::compositor { - -/** - * Class with implementation of mask rasterization - */ -class MaskOperation : public MultiThreadedOperation { - protected: - Mask *mask_; - - /* NOTE: these are used more like aspect, - * but they _do_ impact on mask detail */ - int mask_width_; - int mask_height_; - float mask_width_inv_; /* `1 / mask_width_` */ - float mask_height_inv_; /* `1 / mask_height_` */ - float mask_px_ofs_[2]; - - float frame_shutter_; - int frame_number_; - - bool do_feather_; - - struct MaskRasterHandle *raster_mask_handles_[CMP_NODE_MASK_MBLUR_SAMPLES_MAX]; - unsigned int raster_mask_handle_tot_; - - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - public: - MaskOperation(); - - void init_execution() override; - void deinit_execution() override; - - void set_mask(Mask *mask) - { - mask_ = mask; - } - void set_mask_width(int width) - { - mask_width_ = width; - mask_width_inv_ = 1.0f / (float)width; - mask_px_ofs_[0] = mask_width_inv_ * 0.5f; - } - void set_mask_height(int height) - { - mask_height_ = height; - mask_height_inv_ = 1.0f / (float)height; - mask_px_ofs_[1] = mask_height_inv_ * 0.5f; - } - int get_mask_width() - { - return mask_width_; - } - int get_mask_height() - { - return mask_height_; - } - void set_framenumber(int frame_number) - { - frame_number_ = frame_number; - } - void set_feather(bool feather) - { - do_feather_ = feather; - } - - void set_motion_blur_samples(int samples) - { - raster_mask_handle_tot_ = std::min(std::max(1, samples), CMP_NODE_MASK_MBLUR_SAMPLES_MAX); - } - void set_motion_blur_shutter(float shutter) - { - frame_shutter_ = shutter; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - Vector get_non_null_handles() const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cc b/source/blender/compositor/operations/COM_MathBaseOperation.cc deleted file mode 100644 index abe29702da0..00000000000 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cc +++ /dev/null @@ -1,366 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MathBaseOperation.h" - -#include "BLI_math_rotation.h" - -namespace blender::compositor { - -MathBaseOperation::MathBaseOperation() -{ - /* TODO(manzanilla): after removing tiled implementation, template this class to only add needed - * number of inputs. */ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - use_clamp_ = false; - flags_.can_be_constant = true; -} - -void MathBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - NodeOperationInput *socket; - rcti temp_area = COM_AREA_NONE; - socket = this->get_input_socket(0); - const bool determined = socket->determine_canvas(COM_AREA_NONE, temp_area); - if (determined) { - this->set_canvas_input_index(0); - } - else { - this->set_canvas_input_index(1); - } - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void MathBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - BuffersIterator it = output->iterate_with(inputs, area); - update_memory_buffer_partial(it); -} - -void MathDivideOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float divisor = *it.in(1); - *it.out = clamp_when_enabled((divisor == 0) ? 0 : *it.in(0) / divisor); - } -} - -void MathSineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = sin(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathCosineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = cos(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathTangentOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = tan(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathHyperbolicSineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = sinh(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathHyperbolicCosineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = cosh(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathHyperbolicTangentOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = tanh(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathArcSineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - float value1 = *it.in(0); - *it.out = clamp_when_enabled((value1 <= 1 && value1 >= -1) ? asin(value1) : 0.0f); - } -} - -void MathArcCosineOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - float value1 = *it.in(0); - *it.out = clamp_when_enabled((value1 <= 1 && value1 >= -1) ? acos(value1) : 0.0f); - } -} - -void MathArcTangentOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = atan(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathPowerOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value1 = *it.in(0); - const float value2 = *it.in(1); - if (value1 >= 0) { - *it.out = pow(value1, value2); - } - else { - const float y_mod_1 = fmod(value2, 1); - /* If input value is not nearly an integer, fall back to zero, nicer than straight rounding. - */ - if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) { - *it.out = pow(value1, floorf(value2 + 0.5f)); - } - else { - *it.out = 0.0f; - } - } - clamp_when_enabled(it.out); - } -} - -void MathLogarithmOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value1 = *it.in(0); - const float value2 = *it.in(1); - if (value1 > 0 && value2 > 0) { - *it.out = log(value1) / log(value2); - } - else { - *it.out = 0.0; - } - clamp_when_enabled(it.out); - } -} - -void MathMinimumOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = std::min(*it.in(0), *it.in(1)); - clamp_when_enabled(it.out); - } -} - -void MathMaximumOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = std::max(*it.in(0), *it.in(1)); - clamp_when_enabled(it.out); - } -} - -void MathRoundOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = round(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathModuloOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value2 = *it.in(1); - *it.out = (value2 == 0) ? 0 : fmod(*it.in(0), value2); - clamp_when_enabled(it.out); - } -} - -void MathFlooredModuloOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value2 = *it.in(1); - *it.out = (value2 == 0) ? 0 : *it.in(0) - floorf(*it.in(0) / value2) * value2; - clamp_when_enabled(it.out); - } -} - -void MathAbsoluteOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = fabs(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathRadiansOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = DEG2RADF(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathDegreesOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = RAD2DEGF(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathArcTan2Operation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = atan2(*it.in(0), *it.in(1)); - clamp_when_enabled(it.out); - } -} - -void MathFloorOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = floor(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathCeilOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = ceil(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathFractOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value = *it.in(0); - *it.out = clamp_when_enabled(value - floor(value)); - } -} - -void MathSqrtOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value = *it.in(0); - *it.out = clamp_when_enabled(value > 0 ? sqrt(value) : 0.0f); - } -} - -void MathInverseSqrtOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value = *it.in(0); - *it.out = clamp_when_enabled(value > 0 ? 1.0f / sqrt(value) : 0.0f); - } -} - -void MathSignOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = compatible_signf(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathExponentOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = expf(*it.in(0)); - clamp_when_enabled(it.out); - } -} - -void MathTruncOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value = *it.in(0); - *it.out = (value >= 0.0f) ? floor(value) : ceil(value); - clamp_when_enabled(it.out); - } -} - -void MathSnapOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - const float value1 = *it.in(0); - const float value2 = *it.in(1); - if (value1 == 0 || value2 == 0) { /* Avoid dividing by zero. */ - *it.out = 0.0f; - } - else { - *it.out = floorf(value1 / value2) * value2; - } - clamp_when_enabled(it.out); - } -} - -void MathWrapOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = wrapf(*it.in(0), *it.in(1), *it.in(2)); - clamp_when_enabled(it.out); - } -} - -void MathPingpongOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = pingpongf(*it.in(0), *it.in(1)); - clamp_when_enabled(it.out); - } -} - -void MathCompareOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = (fabsf(*it.in(0) - *it.in(1)) <= std::max(*it.in(2), 1e-5f)) ? 1.0f : 0.0f; - clamp_when_enabled(it.out); - } -} - -void MathMultiplyAddOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = it.in(0)[0] * it.in(1)[0] + it.in(2)[0]; - clamp_when_enabled(it.out); - } -} - -void MathSmoothMinOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = smoothminf(*it.in(0), *it.in(1), *it.in(2)); - clamp_when_enabled(it.out); - } -} - -void MathSmoothMaxOperation::update_memory_buffer_partial(BuffersIterator &it) -{ - for (; !it.is_end(); ++it) { - *it.out = -smoothminf(-it.in(0)[0], -it.in(1)[0], it.in(2)[0]); - clamp_when_enabled(it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h deleted file mode 100644 index d59ec3b579d..00000000000 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ /dev/null @@ -1,241 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class MathBaseOperation : public MultiThreadedOperation { - protected: - bool use_clamp_; - - protected: - MathBaseOperation(); - - float clamp_when_enabled(float value) - { - if (use_clamp_) { - return std::clamp(value, 0.0f, 1.0f); - } - return value; - } - - void clamp_when_enabled(float *out) - { - if (use_clamp_) { - CLAMP(*out, 0.0f, 1.0f); - } - } - - public: - /** - * Determine resolution - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_use_clamp(bool value) - { - use_clamp_ = value; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) final; - - protected: - virtual void update_memory_buffer_partial(BuffersIterator &it) = 0; -}; - -template typename TFunctor> -class MathFunctor2Operation : public MathBaseOperation { - void update_memory_buffer_partial(BuffersIterator &it) final - { - TFunctor functor; - for (; !it.is_end(); ++it) { - *it.out = functor(*it.in(0), *it.in(1)); - clamp_when_enabled(it.out); - } - } -}; - -class MathAddOperation : public MathFunctor2Operation {}; -class MathSubtractOperation : public MathFunctor2Operation {}; -class MathMultiplyOperation : public MathFunctor2Operation {}; -class MathDivideOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathSineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathCosineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathTangentOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathHyperbolicSineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathHyperbolicCosineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathHyperbolicTangentOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathArcSineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathArcCosineOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathArcTangentOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathPowerOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathLogarithmOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathMinimumOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathMaximumOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathRoundOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; -class MathLessThanOperation : public MathFunctor2Operation {}; -class MathGreaterThanOperation : public MathFunctor2Operation {}; - -class MathModuloOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathFlooredModuloOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathAbsoluteOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathRadiansOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathDegreesOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathArcTan2Operation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathFloorOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathCeilOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathFractOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathSqrtOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathInverseSqrtOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathSignOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathExponentOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathTruncOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathSnapOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathWrapOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathPingpongOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathCompareOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathMultiplyAddOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathSmoothMinOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -class MathSmoothMaxOperation : public MathBaseOperation { - protected: - void update_memory_buffer_partial(BuffersIterator &it) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MixOperation.cc b/source/blender/compositor/operations/COM_MixOperation.cc deleted file mode 100644 index 059d810aae9..00000000000 --- a/source/blender/compositor/operations/COM_MixOperation.cc +++ /dev/null @@ -1,659 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MixOperation.h" - -#include "BLI_math_color.h" - -namespace blender::compositor { - -/* ******** Mix Base Operation ******** */ - -MixBaseOperation::MixBaseOperation() -{ - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_use_value_alpha_multiply(false); - this->set_use_clamp(false); - flags_.can_be_constant = true; -} - -void MixBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - NodeOperationInput *socket; - rcti temp_area = COM_AREA_NONE; - - socket = this->get_input_socket(1); - bool determined = socket->determine_canvas(COM_AREA_NONE, temp_area); - if (determined) { - this->set_canvas_input_index(1); - } - else { - socket = this->get_input_socket(2); - determined = socket->determine_canvas(COM_AREA_NONE, temp_area); - if (determined) { - this->set_canvas_input_index(2); - } - else { - this->set_canvas_input_index(0); - } - } - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void MixBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_value = inputs[0]; - const MemoryBuffer *input_color1 = inputs[1]; - const MemoryBuffer *input_color2 = inputs[2]; - const int width = BLI_rcti_size_x(&area); - PixelCursor p; - p.out_stride = output->elem_stride; - p.value_stride = input_value->elem_stride; - p.color1_stride = input_color1->elem_stride; - p.color2_stride = input_color2->elem_stride; - for (int y = area.ymin; y < area.ymax; y++) { - p.out = output->get_elem(area.xmin, y); - p.row_end = p.out + width * output->elem_stride; - p.value = input_value->get_elem(area.xmin, y); - p.color1 = input_color1->get_elem(area.xmin, y); - p.color2 = input_color2->get_elem(area.xmin, y); - update_memory_buffer_row(p); - } -} - -void MixBaseOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - p.out[0] = value_m * p.color1[0] + value * p.color2[0]; - p.out[1] = value_m * p.color1[1] + value * p.color2[1]; - p.out[2] = value_m * p.color1[2] + value * p.color2[2]; - p.out[3] = p.color1[3]; - p.next(); - } -} - -/* ******** Mix Add Operation ******** */ - -void MixAddOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - p.out[0] = p.color1[0] + value * p.color2[0]; - p.out[1] = p.color1[1] + value * p.color2[1]; - p.out[2] = p.color1[2] + value * p.color2[2]; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Blend Operation ******** */ - -void MixBlendOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - float value_m = 1.0f - value; - p.out[0] = value_m * p.color1[0] + value * p.color2[0]; - p.out[1] = value_m * p.color1[1] + value * p.color2[1]; - p.out[2] = value_m * p.color1[2] + value * p.color2[2]; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Burn Operation ******** */ - -void MixColorBurnOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - float tmp = value_m + value * p.color2[0]; - if (tmp <= 0.0f) { - p.out[0] = 0.0f; - } - else { - tmp = 1.0f - (1.0f - p.color1[0]) / tmp; - p.out[0] = std::clamp(tmp, 0.0f, 1.0f); - } - - tmp = value_m + value * p.color2[1]; - if (tmp <= 0.0f) { - p.out[1] = 0.0f; - } - else { - tmp = 1.0f - (1.0f - p.color1[1]) / tmp; - p.out[1] = std::clamp(tmp, 0.0f, 1.0f); - } - - tmp = value_m + value * p.color2[2]; - if (tmp <= 0.0f) { - p.out[2] = 0.0f; - } - else { - tmp = 1.0f - (1.0f - p.color1[2]) / tmp; - p.out[2] = std::clamp(tmp, 0.0f, 1.0f); - } - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Color Operation ******** */ - -void MixColorOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - float colH, colS, colV; - rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV); - if (colS != 0.0f) { - float rH, rS, rV; - float tmpr, tmpg, tmpb; - rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV); - hsv_to_rgb(colH, colS, rV, &tmpr, &tmpg, &tmpb); - p.out[0] = (value_m * p.color1[0]) + (value * tmpr); - p.out[1] = (value_m * p.color1[1]) + (value * tmpg); - p.out[2] = (value_m * p.color1[2]) + (value * tmpb); - } - else { - copy_v3_v3(p.out, p.color1); - } - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Darken Operation ******** */ - -void MixDarkenOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - float value_m = 1.0f - value; - p.out[0] = min_ff(p.color1[0], p.color2[0]) * value + p.color1[0] * value_m; - p.out[1] = min_ff(p.color1[1], p.color2[1]) * value + p.color1[1] * value_m; - p.out[2] = min_ff(p.color1[2], p.color2[2]) * value + p.color1[2] * value_m; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Difference Operation ******** */ - -void MixDifferenceOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - p.out[0] = value_m * p.color1[0] + value * fabsf(p.color1[0] - p.color2[0]); - p.out[1] = value_m * p.color1[1] + value * fabsf(p.color1[1] - p.color2[1]); - p.out[2] = value_m * p.color1[2] + value * fabsf(p.color1[2] - p.color2[2]); - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Exclusion Operation ******** */ - -void MixExclusionOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - p.out[0] = max_ff(value_m * p.color1[0] + - value * (p.color1[0] + p.color2[0] - 2.0f * p.color1[0] * p.color2[0]), - 0.0f); - p.out[1] = max_ff(value_m * p.color1[1] + - value * (p.color1[1] + p.color2[1] - 2.0f * p.color1[1] * p.color2[1]), - 0.0f); - p.out[2] = max_ff(value_m * p.color1[2] + - value * (p.color1[2] + p.color2[2] - 2.0f * p.color1[2] * p.color2[2]), - 0.0f); - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Divide Operation ******** */ - -void MixDivideOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - if (p.color2[0] != 0.0f) { - p.out[0] = value_m * (p.color1[0]) + value * (p.color1[0]) / p.color2[0]; - } - else { - p.out[0] = 0.0f; - } - if (p.color2[1] != 0.0f) { - p.out[1] = value_m * (p.color1[1]) + value * (p.color1[1]) / p.color2[1]; - } - else { - p.out[1] = 0.0f; - } - if (p.color2[2] != 0.0f) { - p.out[2] = value_m * (p.color1[2]) + value * (p.color1[2]) / p.color2[2]; - } - else { - p.out[2] = 0.0f; - } - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Dodge Operation ******** */ - -void MixDodgeOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - - float tmp; - if (p.color1[0] != 0.0f) { - tmp = 1.0f - value * p.color2[0]; - if (tmp <= 0.0f) { - p.out[0] = 1.0f; - } - else { - p.out[0] = p.color1[0] / tmp; - CLAMP_MAX(p.out[0], 1.0f); - } - } - else { - p.out[0] = 0.0f; - } - - if (p.color1[1] != 0.0f) { - tmp = 1.0f - value * p.color2[1]; - if (tmp <= 0.0f) { - p.out[1] = 1.0f; - } - else { - p.out[1] = p.color1[1] / tmp; - CLAMP_MAX(p.out[1], 1.0f); - } - } - else { - p.out[1] = 0.0f; - } - - if (p.color1[2] != 0.0f) { - tmp = 1.0f - value * p.color2[2]; - if (tmp <= 0.0f) { - p.out[2] = 1.0f; - } - else { - p.out[2] = p.color1[2] / tmp; - CLAMP_MAX(p.out[2], 1.0f); - } - } - else { - p.out[2] = 0.0f; - } - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Glare Operation ******** */ - -void MixGlareOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - const float value = p.value[0]; - /* Linear interpolation between 3 cases: - * value=-1:output=input value=0:output=input+glare value=1:output=glare - */ - float input_weight; - float glare_weight; - if (value < 0.0f) { - input_weight = 1.0f; - glare_weight = 1.0f + value; - } - else { - input_weight = 1.0f - value; - glare_weight = 1.0f; - } - p.out[0] = input_weight * std::max(p.color1[0], 0.0f) + glare_weight * p.color2[0]; - p.out[1] = input_weight * std::max(p.color1[1], 0.0f) + glare_weight * p.color2[1]; - p.out[2] = input_weight * std::max(p.color1[2], 0.0f) + glare_weight * p.color2[2]; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Hue Operation ******** */ - -void MixHueOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - float colH, colS, colV; - rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV); - if (colS != 0.0f) { - float rH, rS, rV; - float tmpr, tmpg, tmpb; - rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV); - hsv_to_rgb(colH, rS, rV, &tmpr, &tmpg, &tmpb); - p.out[0] = value_m * p.color1[0] + value * tmpr; - p.out[1] = value_m * p.color1[1] + value * tmpg; - p.out[2] = value_m * p.color1[2] + value * tmpb; - } - else { - copy_v3_v3(p.out, p.color1); - } - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Lighten Operation ******** */ - -void MixLightenOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - float value_m = 1.0f - value; - p.out[0] = max_ff(p.color1[0], p.color2[0]) * value + p.color1[0] * value_m; - p.out[1] = max_ff(p.color1[1], p.color2[1]) * value + p.color1[1] * value_m; - p.out[2] = max_ff(p.color1[2], p.color2[2]) * value + p.color1[2] * value_m; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Linear Light Operation ******** */ - -void MixLinearLightOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - if (p.color2[0] > 0.5f) { - p.out[0] = p.color1[0] + value * (2.0f * (p.color2[0] - 0.5f)); - } - else { - p.out[0] = p.color1[0] + value * (2.0f * (p.color2[0]) - 1.0f); - } - if (p.color2[1] > 0.5f) { - p.out[1] = p.color1[1] + value * (2.0f * (p.color2[1] - 0.5f)); - } - else { - p.out[1] = p.color1[1] + value * (2.0f * (p.color2[1]) - 1.0f); - } - if (p.color2[2] > 0.5f) { - p.out[2] = p.color1[2] + value * (2.0f * (p.color2[2] - 0.5f)); - } - else { - p.out[2] = p.color1[2] + value * (2.0f * (p.color2[2]) - 1.0f); - } - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Multiply Operation ******** */ - -void MixMultiplyOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - p.out[0] = p.color1[0] * (value_m + value * p.color2[0]); - p.out[1] = p.color1[1] * (value_m + value * p.color2[1]); - p.out[2] = p.color1[2] * (value_m + value * p.color2[2]); - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Overlay Operation ******** */ - -void MixOverlayOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - if (p.color1[0] < 0.5f) { - p.out[0] = p.color1[0] * (value_m + 2.0f * value * p.color2[0]); - } - else { - p.out[0] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[0])) * (1.0f - p.color1[0]); - } - if (p.color1[1] < 0.5f) { - p.out[1] = p.color1[1] * (value_m + 2.0f * value * p.color2[1]); - } - else { - p.out[1] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[1])) * (1.0f - p.color1[1]); - } - if (p.color1[2] < 0.5f) { - p.out[2] = p.color1[2] * (value_m + 2.0f * value * p.color2[2]); - } - else { - p.out[2] = 1.0f - (value_m + 2.0f * value * (1.0f - p.color2[2])) * (1.0f - p.color1[2]); - } - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Saturation Operation ******** */ - -void MixSaturationOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - float rH, rS, rV; - rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV); - if (rS != 0.0f) { - float colH, colS, colV; - rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV); - hsv_to_rgb(rH, (value_m * rS + value * colS), rV, &p.out[0], &p.out[1], &p.out[2]); - } - else { - copy_v3_v3(p.out, p.color1); - } - - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Screen Operation ******** */ - -void MixScreenOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - - p.out[0] = 1.0f - (value_m + value * (1.0f - p.color2[0])) * (1.0f - p.color1[0]); - p.out[1] = 1.0f - (value_m + value * (1.0f - p.color2[1])) * (1.0f - p.color1[1]); - p.out[2] = 1.0f - (value_m + value * (1.0f - p.color2[2])) * (1.0f - p.color1[2]); - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Soft Light Operation ******** */ - -void MixSoftLightOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - const float value_m = 1.0f - value; - float scr, scg, scb; - - /* First calculate non-fac based Screen mix. */ - scr = 1.0f - (1.0f - p.color2[0]) * (1.0f - p.color1[0]); - scg = 1.0f - (1.0f - p.color2[1]) * (1.0f - p.color1[1]); - scb = 1.0f - (1.0f - p.color2[2]) * (1.0f - p.color1[2]); - - p.out[0] = value_m * p.color1[0] + - value * ((1.0f - p.color1[0]) * p.color2[0] * p.color1[0] + p.color1[0] * scr); - p.out[1] = value_m * p.color1[1] + - value * ((1.0f - p.color1[1]) * p.color2[1] * p.color1[1] + p.color1[1] * scg); - p.out[2] = value_m * p.color1[2] + - value * ((1.0f - p.color1[2]) * p.color2[2] * p.color1[2] + p.color1[2] * scb); - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Subtract Operation ******** */ - -void MixSubtractOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - p.out[0] = p.color1[0] - value * p.color2[0]; - p.out[1] = p.color1[1] - value * p.color2[1]; - p.out[2] = p.color1[2] - value * p.color2[2]; - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -/* ******** Mix Value Operation ******** */ - -void MixValueOperation::update_memory_buffer_row(PixelCursor &p) -{ - while (p.out < p.row_end) { - float value = p.value[0]; - if (this->use_value_alpha_multiply()) { - value *= p.color2[3]; - } - float value_m = 1.0f - value; - - float rH, rS, rV; - float colH, colS, colV; - rgb_to_hsv(p.color1[0], p.color1[1], p.color1[2], &rH, &rS, &rV); - rgb_to_hsv(p.color2[0], p.color2[1], p.color2[2], &colH, &colS, &colV); - hsv_to_rgb(rH, rS, (value_m * rV + value * colV), &p.out[0], &p.out[1], &p.out[2]); - p.out[3] = p.color1[3]; - - clamp_if_needed(p.out); - p.next(); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h deleted file mode 100644 index 7d6ebbb083e..00000000000 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ /dev/null @@ -1,174 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * All this programs converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class MixBaseOperation : public MultiThreadedOperation { - protected: - struct PixelCursor { - float *out; - const float *row_end; - const float *value; - const float *color1; - const float *color2; - int out_stride; - int value_stride; - int color1_stride; - int color2_stride; - - void next() - { - BLI_assert(out < row_end); - out += out_stride; - value += value_stride; - color1 += color1_stride; - color2 += color2_stride; - } - }; - - bool value_alpha_multiply_; - bool use_clamp_; - - inline void clamp_if_needed(float color[4]) - { - if (use_clamp_) { - clamp_v4(color, 0.0f, 1.0f); - } - } - - public: - MixBaseOperation(); - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_use_value_alpha_multiply(const bool value) - { - value_alpha_multiply_ = value; - } - inline bool use_value_alpha_multiply() - { - return value_alpha_multiply_; - } - void set_use_clamp(bool value) - { - use_clamp_ = value; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) final; - - protected: - virtual void update_memory_buffer_row(PixelCursor &p); -}; - -class MixAddOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixBlendOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixColorBurnOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixColorOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixDarkenOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixDifferenceOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixExclusionOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixDivideOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixDodgeOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixGlareOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixHueOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixLightenOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixLinearLightOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixMultiplyOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixOverlayOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixSaturationOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixScreenOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixSoftLightOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixSubtractOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -class MixValueOperation : public MixBaseOperation { - protected: - void update_memory_buffer_row(PixelCursor &p) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cc b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cc deleted file mode 100644 index 4e3b2009b44..00000000000 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MovieClipAttributeOperation.h" - -#include "BKE_movieclip.h" -#include "BKE_tracking.h" - -namespace blender::compositor { - -MovieClipAttributeOperation::MovieClipAttributeOperation() -{ - this->add_output_socket(DataType::Value); - framenumber_ = 0; - attribute_ = MCA_X; - invert_ = false; - needs_canvas_to_get_constant_ = true; - is_value_calculated_ = false; - stabilization_resolution_socket_ = nullptr; -} - -void MovieClipAttributeOperation::init_execution() -{ - if (!is_value_calculated_) { - calc_value(); - } -} - -void MovieClipAttributeOperation::calc_value() -{ - BLI_assert(this->get_flags().is_canvas_set); - is_value_calculated_ = true; - if (clip_ == nullptr) { - return; - } - float loc[2], scale, angle; - loc[0] = 0.0f; - loc[1] = 0.0f; - scale = 1.0f; - angle = 0.0f; - int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip_, framenumber_); - NodeOperation &stabilization_operation = - stabilization_resolution_socket_ ? - stabilization_resolution_socket_->get_link()->get_operation() : - *this; - BKE_tracking_stabilization_data_get(clip_, - clip_framenr, - stabilization_operation.get_width(), - stabilization_operation.get_height(), - loc, - &scale, - &angle); - switch (attribute_) { - case MCA_SCALE: - value_ = scale; - break; - case MCA_ANGLE: - value_ = angle; - break; - case MCA_X: - value_ = loc[0]; - break; - case MCA_Y: - value_ = loc[1]; - break; - } - if (invert_) { - if (attribute_ != MCA_SCALE) { - value_ = -value_; - } - else { - value_ = 1.0f / value_; - } - } -} - -void MovieClipAttributeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; -} - -const float *MovieClipAttributeOperation::get_constant_elem() -{ - if (!is_value_calculated_) { - calc_value(); - } - return &value_; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h deleted file mode 100644 index 13a8b3f29e6..00000000000 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConstantOperation.h" -#include "COM_NodeOperation.h" -#include "DNA_movieclip_types.h" - -namespace blender::compositor { - -typedef enum MovieClipAttribute { - MCA_SCALE, - MCA_X, - MCA_Y, - MCA_ANGLE, -} MovieClipAttribute; -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class MovieClipAttributeOperation : public ConstantOperation { - private: - MovieClip *clip_; - float value_; - int framenumber_; - bool invert_; - MovieClipAttribute attribute_; - bool is_value_calculated_; - NodeOperationInput *stabilization_resolution_socket_; - - public: - /** - * Default constructor - */ - MovieClipAttributeOperation(); - - void init_execution() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - const float *get_constant_elem() override; - - void set_movie_clip(MovieClip *clip) - { - clip_ = clip; - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - void set_attribute(MovieClipAttribute attribute) - { - attribute_ = attribute; - } - void set_invert(bool invert) - { - invert_ = invert; - } - - /** - * Set an operation socket which input will be used to get the resolution for stabilization. - */ - void set_socket_input_resolution_for_stabilization(NodeOperationInput *input_socket) - { - stabilization_resolution_socket_ = input_socket; - } - - private: - void calc_value(); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cc b/source/blender/compositor/operations/COM_MovieClipOperation.cc deleted file mode 100644 index 62eadbd9220..00000000000 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MovieClipOperation.h" - -#include "BKE_image.hh" -#include "BKE_movieclip.h" - -#include "IMB_imbuf.hh" -#include "IMB_interp.hh" - -namespace blender::compositor { - -MovieClipBaseOperation::MovieClipBaseOperation() -{ - movie_clip_ = nullptr; - movie_clip_buffer_ = nullptr; - movie_clip_user_ = nullptr; - movie_clipwidth_ = 0; - movie_clipheight_ = 0; - framenumber_ = 0; -} - -void MovieClipBaseOperation::init_execution() -{ - if (movie_clip_) { - BKE_movieclip_user_set_frame(movie_clip_user_, framenumber_); - ImBuf *ibuf; - - if (cache_frame_) { - ibuf = BKE_movieclip_get_ibuf(movie_clip_, movie_clip_user_); - } - else { - ibuf = BKE_movieclip_get_ibuf_flag( - movie_clip_, movie_clip_user_, movie_clip_->flag, MOVIECLIP_CACHE_SKIP); - } - - if (ibuf) { - movie_clip_buffer_ = ibuf; - if (ibuf->float_buffer.data == nullptr || ibuf->userflags & IB_RECT_INVALID) { - IMB_float_from_rect(ibuf); - ibuf->userflags &= ~IB_RECT_INVALID; - } - } - } -} - -void MovieClipBaseOperation::deinit_execution() -{ - if (movie_clip_buffer_) { - IMB_freeImBuf(movie_clip_buffer_); - - movie_clip_buffer_ = nullptr; - } -} - -void MovieClipBaseOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - r_area = COM_AREA_NONE; - if (movie_clip_) { - int width, height; - BKE_movieclip_get_size(movie_clip_, movie_clip_user_, &width, &height); - BLI_rcti_init(&r_area, 0, width, 0, height); - } -} - -void MovieClipBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - if (movie_clip_buffer_) { - output->copy_from(movie_clip_buffer_, area); - } - else { - output->fill(area, COM_COLOR_TRANSPARENT); - } -} - -MovieClipOperation::MovieClipOperation() : MovieClipBaseOperation() -{ - this->add_output_socket(DataType::Color); -} - -MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation() -{ - this->add_output_socket(DataType::Value); -} - -void MovieClipAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - if (movie_clip_buffer_) { - output->copy_from(movie_clip_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); - } - else { - output->fill(area, COM_VALUE_ZERO); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h deleted file mode 100644 index 1df02a380f0..00000000000 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_listbase.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_movieclip_types.h" -#include "IMB_imbuf_types.hh" - -namespace blender::compositor { - -/** - * Base class for movie clip - */ -class MovieClipBaseOperation : public MultiThreadedOperation { - protected: - MovieClip *movie_clip_; - MovieClipUser *movie_clip_user_; - ImBuf *movie_clip_buffer_; - int movie_clipheight_; - int movie_clipwidth_; - int framenumber_; - bool cache_frame_; - - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - public: - MovieClipBaseOperation(); - - void init_execution() override; - void deinit_execution() override; - void set_movie_clip(MovieClip *image) - { - movie_clip_ = image; - } - void set_movie_clip_user(MovieClipUser *imageuser) - { - movie_clip_user_ = imageuser; - } - void set_cache_frame(bool value) - { - cache_frame_ = value; - } - - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class MovieClipOperation : public MovieClipBaseOperation { - public: - MovieClipOperation(); -}; - -class MovieClipAlphaOperation : public MovieClipBaseOperation { - public: - MovieClipAlphaOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc deleted file mode 100644 index 36c7414e37d..00000000000 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MovieDistortionOperation.h" - -#include "DNA_defaults.h" - -#include "BKE_movieclip.h" - -namespace blender::compositor { - -MovieDistortionOperation::MovieDistortionOperation(bool distortion) -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - movie_clip_ = nullptr; - apply_ = distortion; - - flags_.can_be_constant = true; -} - -void MovieDistortionOperation::init_data() -{ - if (movie_clip_) { - MovieTracking *tracking = &movie_clip_->tracking; - MovieClipUser clip_user = *DNA_struct_default_get(MovieClipUser); - int calibration_width, calibration_height; - - BKE_movieclip_user_set_frame(&clip_user, framenumber_); - BKE_movieclip_get_size(movie_clip_, &clip_user, &calibration_width, &calibration_height); - - float delta[2]; - rcti full_frame; - full_frame.xmin = full_frame.ymin = 0; - full_frame.xmax = this->get_width(); - full_frame.ymax = this->get_height(); - BKE_tracking_max_distortion_delta_across_bound( - tracking, this->get_width(), this->get_height(), &full_frame, !apply_, delta); - - /* 5 is just in case we didn't hit real max of distortion in - * BKE_tracking_max_undistortion_delta_across_bound - */ - margin_[0] = delta[0] + 5; - margin_[1] = delta[1] + 5; - - calibration_width_ = calibration_width; - calibration_height_ = calibration_height; - pixel_aspect_ = tracking->camera.pixel_aspect; - } - else { - margin_[0] = margin_[1] = 0; - } -} - -void MovieDistortionOperation::init_execution() -{ - if (movie_clip_) { - MovieTracking *tracking = &movie_clip_->tracking; - distortion_ = BKE_tracking_distortion_new(tracking, calibration_width_, calibration_height_); - } - else { - distortion_ = nullptr; - } -} - -void MovieDistortionOperation::deinit_execution() -{ - movie_clip_ = nullptr; - if (distortion_ != nullptr) { - BKE_tracking_distortion_free(distortion_); - } -} - -void MovieDistortionOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - r_input_area.xmin = output_area.xmin - margin_[0]; - r_input_area.ymin = output_area.ymin - margin_[1]; - r_input_area.xmax = output_area.xmax + margin_[0]; - r_input_area.ymax = output_area.ymax + margin_[1]; -} - -void MovieDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[0]; - if (distortion_ == nullptr) { - output->copy_from(input_img, area); - return; - } - - /* `float overscan = 0.0f;` */ - const float pixel_aspect = pixel_aspect_; - const float w = float(this->get_width()) /* `/ (1 + overscan)` */; - const float h = float(this->get_height()) /* `/ (1 + overscan)` */; - const float aspx = w / float(calibration_width_); - const float aspy = h / float(calibration_height_); - float xy[2]; - float distorted_xy[2]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - xy[0] = (it.x + 0.5f /* `- 0.5 * overscan * w` */) / aspx; - xy[1] = (it.y + 0.5f /* `- 0.5 * overscan * h` */) / aspy / pixel_aspect; - - if (apply_) { - BKE_tracking_distortion_undistort_v2(distortion_, xy, distorted_xy); - } - else { - BKE_tracking_distortion_distort_v2(distortion_, xy, distorted_xy); - } - - const float u = distorted_xy[0] * aspx /* `+ 0.5 * overscan * w` */; - const float v = (distorted_xy[1] * aspy /* `+ 0.5 * overscan * h` */) * pixel_aspect; - input_img->read_elem_bilinear(u - 0.5f, v - 0.5f, it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h deleted file mode 100644 index 2d1f9f94a6c..00000000000 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_movieclip_types.h" -#include "MEM_guardedalloc.h" - -#include "BKE_tracking.h" - -namespace blender::compositor { - -class MovieDistortionOperation : public MultiThreadedOperation { - private: - MovieClip *movie_clip_; - int margin_[2]; - - protected: - bool apply_; - int framenumber_; - - struct MovieDistortion *distortion_; - int calibration_width_, calibration_height_; - float pixel_aspect_; - - public: - MovieDistortionOperation(bool distortion); - - void init_data() override; - void init_execution() override; - void deinit_execution() override; - - void set_movie_clip(MovieClip *clip) - { - movie_clip_ = clip; - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc deleted file mode 100644 index 2b8f719bfc3..00000000000 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_MultilayerImageOperation.h" - -#include "BLI_string.h" - -#include "IMB_interp.hh" - -namespace blender::compositor { - -ImBuf *MultilayerBaseOperation::get_im_buf() -{ - if (rd_ == nullptr || image_ == nullptr) { - return nullptr; - } - - ImBuf *ibuf = BKE_image_acquire_multilayer_view_ibuf( - *rd_, *image_, image_user_, pass_name_.c_str(), view_name_); - if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) - { - BKE_image_release_ibuf(image_, ibuf, nullptr); - return nullptr; - } - return ibuf; -} - -void MultilayerBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - if (buffer_) { - output->copy_from(buffer_, area); - } - else { - output->clear(); - } -} - -std::unique_ptr MultilayerColorOperation::get_meta_data() -{ - BLI_assert(buffer_); - - if (!image_) { - return nullptr; - } - - MetaDataExtractCallbackData callback_data = {nullptr}; - std::string full_layer_name = layer_name_ + "." + pass_name_; - blender::StringRef cryptomatte_layer_name = - blender::bke::cryptomatte::BKE_cryptomatte_extract_layer_name(full_layer_name); - callback_data.set_cryptomatte_keys(cryptomatte_layer_name); - - BKE_image_multilayer_stamp_info_callback( - &callback_data, *image_, MetaDataExtractCallbackData::extract_cryptomatte_meta_data, false); - - return std::move(callback_data.meta_data); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h deleted file mode 100644 index 5addbd3e73a..00000000000 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_ImageOperation.h" - -namespace blender::compositor { - -class MultilayerBaseOperation : public BaseImageOperation { - protected: - /* NOTE: The layer name is only used for meta-data. The image user's layer index defines which - * layer will be actually accessed for the image buffer. */ - std::string layer_name_; - std::string pass_name_; - - ImBuf *get_im_buf() override; - - public: - MultilayerBaseOperation() = default; - - void set_layer_name(std::string layer_name) - { - layer_name_ = std::move(layer_name); - } - void set_pass_name(std::string pass_name) - { - pass_name_ = std::move(pass_name); - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class MultilayerColorOperation : public MultilayerBaseOperation { - public: - MultilayerColorOperation() - { - this->add_output_socket(DataType::Color); - } - std::unique_ptr get_meta_data() override; -}; - -class MultilayerValueOperation : public MultilayerBaseOperation { - public: - MultilayerValueOperation() - { - this->add_output_socket(DataType::Value); - } -}; - -class MultilayerVectorOperation : public MultilayerBaseOperation { - public: - MultilayerVectorOperation() - { - this->add_output_socket(DataType::Vector); - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cc b/source/blender/compositor/operations/COM_NormalizeOperation.cc deleted file mode 100644 index 5cd8f3e9dc9..00000000000 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_NormalizeOperation.h" - -namespace blender::compositor { - -NormalizeOperation::NormalizeOperation() -{ - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Value); - cached_instance_ = nullptr; - flags_.can_be_constant = true; -} - -void NormalizeOperation::deinit_execution() -{ - delete cached_instance_; - cached_instance_ = nullptr; -} - -/* The code below assumes all data is inside range +- this, and that input buffer is single channel - */ -#define BLENDER_ZMAX 10000.0f - -void NormalizeOperation::get_area_of_interest(const int /*input_idx*/, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - r_input_area = get_input_operation(0)->get_canvas(); -} - -void NormalizeOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span inputs) -{ - if (cached_instance_ == nullptr) { - MemoryBuffer *input = inputs[0]; - - /* Using generic two floats struct to store `x: min`, `y: multiply`. */ - NodeTwoFloats *minmult = new NodeTwoFloats(); - - float minv = 1.0f + BLENDER_ZMAX; - float maxv = -1.0f - BLENDER_ZMAX; - for (const float *elem : input->as_range()) { - const float value = *elem; - if ((value > maxv) && (value <= BLENDER_ZMAX)) { - maxv = value; - } - if ((value < minv) && (value >= -BLENDER_ZMAX)) { - minv = value; - } - } - - minmult->x = minv; - /* The case of a flat buffer would cause a divide by 0. */ - minmult->y = ((maxv != minv) ? 1.0f / (maxv - minv) : 0.0f); - - cached_instance_ = minmult; - } -} - -void NormalizeOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - NodeTwoFloats *minmult = cached_instance_; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float input_value = *it.in(0); - - *it.out = (input_value - minmult->x) * minmult->y; - - /* Clamp infinities. */ - CLAMP(*it.out, 0.0f, 1.0f); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h deleted file mode 100644 index 50ec78fdd8a..00000000000 --- a/source/blender/compositor/operations/COM_NormalizeOperation.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief base class of normalize, implementing the simple normalize - * \ingroup operation - */ -class NormalizeOperation : public MultiThreadedOperation { - protected: - /** - * \brief temporarily cache of the execution storage - * it stores `x->min` and `y->multiply`. - */ - NodeTwoFloats *cached_instance_; - - public: - NormalizeOperation(); - - void deinit_execution() override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PixelateOperation.cc b/source/blender/compositor/operations/COM_PixelateOperation.cc deleted file mode 100644 index 9e07173a170..00000000000 --- a/source/blender/compositor/operations/COM_PixelateOperation.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PixelateOperation.h" - -#include - -namespace blender::compositor { - -PixelateOperation::PixelateOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - - flags_.can_be_constant = true; - - pixel_size_ = 1; -} - -void PixelateOperation::get_area_of_interest(const int /*input_idx*/, - const rcti &output_area, - rcti &r_input_area) -{ - r_input_area.xmin = output_area.xmin; - r_input_area.ymin = output_area.ymin; - - r_input_area.xmax = output_area.xmax + pixel_size_ - 1; - r_input_area.ymax = output_area.ymax + pixel_size_ - 1; -} - -void PixelateOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *image = inputs[0]; - - if (image->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), image->get_elem(0, 0)); - return; - } - - const int width = image->get_width(); - const int height = image->get_height(); - - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int x_start = (it.x / pixel_size_) * pixel_size_; - const int y_start = (it.y / pixel_size_) * pixel_size_; - - const int x_end = std::min(x_start + pixel_size_, width); - const int y_end = std::min(y_start + pixel_size_, height); - - float4 color_accum(0, 0, 0, 0); - - for (int y = y_start; y < y_end; ++y) { - for (int x = x_start; x < x_end; ++x) { - float4 color; - image->read_elem(x, y, color); - - color_accum += color; - } - } - - const int scale = (x_end - x_start) * (y_end - y_start); - - copy_v4_v4(it.out, color_accum / float(scale)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h deleted file mode 100644 index e4479354562..00000000000 --- a/source/blender/compositor/operations/COM_PixelateOperation.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class PixelateOperation : public MultiThreadedOperation { - private: - int pixel_size_; - - public: - PixelateOperation(); - - void set_pixel_size(const int pixel_size) - { - if (pixel_size < 1) { - pixel_size_ = 1; - return; - } - pixel_size_ = pixel_size; - } - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc deleted file mode 100644 index ecd70de6566..00000000000 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PlaneCornerPinOperation.h" -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -constexpr int LOWER_LEFT_CORNER_INDEX = 0; -constexpr int LOWER_RIGHT_CORNER_INDEX = 1; -constexpr int UPPER_RIGHT_CORNER_INDEX = 2; -constexpr int UPPER_LEFT_CORNER_INDEX = 3; - -static bool check_corners(float corners[4][2]) -{ - int i, next, prev; - float cross = 0.0f; - - for (i = 0; i < 4; i++) { - float v1[2], v2[2], cur_cross; - - next = (i + 1) % 4; - prev = (4 + i - 1) % 4; - - sub_v2_v2v2(v1, corners[i], corners[prev]); - sub_v2_v2v2(v2, corners[next], corners[i]); - - cur_cross = cross_v2v2(v1, v2); - if (fabsf(cur_cross) <= FLT_EPSILON) { - return false; - } - - if (cross == 0.0f) { - cross = cur_cross; - } - else if (cross * cur_cross < 0.0f) { - return false; - } - } - - return true; -} - -static void set_default_corner(const int corner_idx, float r_corner[2]) -{ - BLI_assert(corner_idx >= 0 && corner_idx < 4); - switch (corner_idx) { - case LOWER_LEFT_CORNER_INDEX: - r_corner[0] = 0.0f; - r_corner[1] = 0.0f; - break; - case LOWER_RIGHT_CORNER_INDEX: - r_corner[0] = 1.0f; - r_corner[1] = 0.0f; - break; - case UPPER_RIGHT_CORNER_INDEX: - r_corner[0] = 1.0f; - r_corner[1] = 1.0f; - break; - case UPPER_LEFT_CORNER_INDEX: - r_corner[0] = 0.0f; - r_corner[1] = 1.0f; - break; - } -} - -static void read_input_corners(NodeOperation *op, const int first_input_idx, float r_corners[4][2]) -{ - for (const int i : IndexRange(4)) { - NodeOperation *input = op->get_input_operation(i + first_input_idx); - if (input->get_flags().is_constant_operation) { - ConstantOperation *corner_input = static_cast(input); - copy_v2_v2(r_corners[i], corner_input->get_constant_elem()); - } - else { - set_default_corner(i, r_corners[i]); - } - } - - /* Convexity check: concave corners need to be prevented, otherwise - * #BKE_tracking_homography_between_two_quads will freeze. */ - if (!check_corners(r_corners)) { - /* Revert to default corners. There could be a more elegant solution, - * this prevents freezing at least. */ - for (const int i : IndexRange(4)) { - set_default_corner(i, r_corners[i]); - } - } -} - -/* ******** PlaneCornerPinMaskOperation ******** */ - -PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() -{ - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); -} - -void PlaneCornerPinMaskOperation::init_data() -{ - float corners[4][2]; - read_input_corners(this, 0, corners); - calculate_corners(corners, true, 0); -} - -void PlaneCornerPinMaskOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - /* Determine input canvases. */ - PlaneDistortMaskOperation::determine_canvas(preferred_area, r_area); - r_area = preferred_area; -} - -void PlaneCornerPinMaskOperation::get_area_of_interest(const int /*input_idx*/, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - /* All corner inputs are used as constants. */ - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; -} - -/* ******** PlaneCornerPinWarpImageOperation ******** */ - -PlaneCornerPinWarpImageOperation::PlaneCornerPinWarpImageOperation() -{ - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); - add_input_socket(DataType::Vector); -} - -void PlaneCornerPinWarpImageOperation::init_data() -{ - float corners[4][2]; - read_input_corners(this, 1, corners); - calculate_corners(corners, true, 0); -} - -void PlaneCornerPinWarpImageOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx == 0) { - PlaneDistortWarpImageOperation::get_area_of_interest(input_idx, output_area, r_input_area); - } - else { - /* Corner inputs are used as constants. */ - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h deleted file mode 100644 index fdc8fd8a300..00000000000 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_PlaneDistortCommonOperation.h" - -namespace blender::compositor { - -class PlaneCornerPinMaskOperation : public PlaneDistortMaskOperation { - public: - PlaneCornerPinMaskOperation(); - - void init_data() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; -}; - -class PlaneCornerPinWarpImageOperation : public PlaneDistortWarpImageOperation { - public: - PlaneCornerPinWarpImageOperation(); - - void init_data() override; - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc deleted file mode 100644 index 148d9b1746d..00000000000 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc +++ /dev/null @@ -1,203 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PlaneDistortCommonOperation.h" - -#include "BLI_jitter_2d.h" -#include "BLI_math_geom.h" -#include "BLI_math_matrix.h" - -#include "BKE_tracking.h" - -namespace blender::compositor { - -PlaneDistortBaseOperation::PlaneDistortBaseOperation() - : motion_blur_samples_(1), motion_blur_shutter_(0.5f) -{ -} - -void PlaneDistortBaseOperation::calculate_corners(const float corners[4][2], - bool normalized, - int sample) -{ - BLI_assert(sample < motion_blur_samples_); - MotionSample *sample_data = &samples_[sample]; - if (normalized) { - for (int i = 0; i < 4; i++) { - sample_data->frame_space_corners[i][0] = corners[i][0] * this->get_width(); - sample_data->frame_space_corners[i][1] = corners[i][1] * this->get_height(); - } - } - else { - for (int i = 0; i < 4; i++) { - sample_data->frame_space_corners[i][0] = corners[i][0]; - sample_data->frame_space_corners[i][1] = corners[i][1]; - } - } -} - -/* ******** PlaneDistort WarpImage ******** */ - -BLI_INLINE void warp_coord(float x, float y, float matrix[3][3], float uv[2], float deriv[2][2]) -{ - float vec[3] = {x, y, 1.0f}; - mul_m3_v3(matrix, vec); - uv[0] = vec[0] / vec[2]; - uv[1] = vec[1] / vec[2]; - - /* Offset so that pixel center corresponds to a (0.5, 0.5), which helps keeping transformed - * image sharp. */ - uv[0] += 0.5f; - uv[1] += 0.5f; - - deriv[0][0] = (matrix[0][0] - matrix[0][2] * uv[0]) / vec[2]; - deriv[1][0] = (matrix[0][1] - matrix[0][2] * uv[1]) / vec[2]; - deriv[0][1] = (matrix[1][0] - matrix[1][2] * uv[0]) / vec[2]; - deriv[1][1] = (matrix[1][1] - matrix[1][2] * uv[1]) / vec[2]; -} - -PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() : PlaneDistortBaseOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_output_socket(DataType::Color); -} - -void PlaneDistortWarpImageOperation::calculate_corners(const float corners[4][2], - bool normalized, - int sample) -{ - PlaneDistortBaseOperation::calculate_corners(corners, normalized, sample); - - const NodeOperation *image = get_input_operation(0); - const int width = image->get_width(); - const int height = image->get_height(); - - MotionSample *sample_data = &samples_[sample]; - - /* If the image which is to be warped empty assume unit transform and don't attempt to calculate - * actual homography (otherwise homography solver will attempt to deal with singularity). */ - if (width == 0 || height == 0) { - unit_m3(sample_data->perspective_matrix); - return; - } - - float frame_corners[4][2] = { - {0.0f, 0.0f}, {float(width), 0.0f}, {float(width), float(height)}, {0.0f, float(height)}}; - BKE_tracking_homography_between_two_quads( - sample_data->frame_space_corners, frame_corners, sample_data->perspective_matrix); -} - -void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[0]; - float uv[2]; - float deriv[2][2]; - BuffersIterator it = output->iterate_with({}, area); - if (motion_blur_samples_ == 1) { - for (; !it.is_end(); ++it) { - warp_coord(it.x, it.y, samples_[0].perspective_matrix, uv, deriv); - input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], true, it.out); - } - } - else { - for (; !it.is_end(); ++it) { - zero_v4(it.out); - for (const int sample : IndexRange(motion_blur_samples_)) { - float color[4]; - warp_coord(it.x, it.y, samples_[sample].perspective_matrix, uv, deriv); - input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], true, color); - add_v4_v4(it.out, color); - } - mul_v4_fl(it.out, 1.0f / float(motion_blur_samples_)); - } - } -} - -void PlaneDistortWarpImageOperation::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; - } - - /* TODO: figure out the area needed for warping and EWA filtering. */ - r_input_area = get_input_operation(0)->get_canvas(); - -/* Old implementation but resulting coordinates are way out of input operation bounds and in some - * cases the area result may incorrectly cause cropping. */ -#if 0 - float min[2], max[2]; - INIT_MINMAX2(min, max); - for (int sample = 0; sample < motion_blur_samples_; sample++) { - float UVs[4][2]; - float deriv[2][2]; - MotionSample *sample_data = &samples_[sample]; - /* TODO(sergey): figure out proper way to do this. */ - warp_coord(output_area.xmin - 2, - output_area.ymin - 2, - sample_data->perspective_matrix, - UVs[0], - deriv); - warp_coord(output_area.xmax + 2, - output_area.ymin - 2, - sample_data->perspective_matrix, - UVs[1], - deriv); - warp_coord(output_area.xmax + 2, - output_area.ymax + 2, - sample_data->perspective_matrix, - UVs[2], - deriv); - warp_coord(output_area.xmin - 2, - output_area.ymax + 2, - sample_data->perspective_matrix, - UVs[3], - deriv); - for (int i = 0; i < 4; i++) { - minmax_v2v2_v2(min, max, UVs[i]); - } - } - - r_input_area.xmin = min[0] - 1; - r_input_area.ymin = min[1] - 1; - r_input_area.xmax = max[0] + 1; - r_input_area.ymax = max[1] + 1; -#endif -} - -/* ******** PlaneDistort Mask ******** */ - -PlaneDistortMaskOperation::PlaneDistortMaskOperation() : PlaneDistortBaseOperation() -{ - add_output_socket(DataType::Value); -} - -void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float accumulated_mask = 0.0f; - const float2 point = float2(it.x, it.y) + 0.5f; - for (const int motion_sample : IndexRange(motion_blur_samples_)) { - MotionSample &sample = samples_[motion_sample]; - const bool is_inside_plane = isect_point_tri_v2(point, - sample.frame_space_corners[0], - sample.frame_space_corners[1], - sample.frame_space_corners[2]) || - isect_point_tri_v2(point, - sample.frame_space_corners[0], - sample.frame_space_corners[2], - sample.frame_space_corners[3]); - accumulated_mask += is_inside_plane ? 1.0f : 0.0f; - } - *it.out = accumulated_mask / motion_blur_samples_; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h deleted file mode 100644 index 269a26261d6..00000000000 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_MultiThreadedOperation.h" - -#include "DNA_movieclip_types.h" -#include "DNA_tracking_types.h" - -#include "BLI_listbase.h" -#include "BLI_string.h" - -namespace blender::compositor { - -#define PLANE_DISTORT_MAX_SAMPLES 64 - -class PlaneDistortBaseOperation : public MultiThreadedOperation { - protected: - struct MotionSample { - float frame_space_corners[4][2]; /* Corners coordinates in pixel space. */ - float perspective_matrix[3][3]; - }; - MotionSample samples_[PLANE_DISTORT_MAX_SAMPLES]; - int motion_blur_samples_; - float motion_blur_shutter_; - - public: - PlaneDistortBaseOperation(); - - void set_motion_blur_samples(int samples) - { - BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES); - motion_blur_samples_ = samples; - } - void set_motion_blur_shutter(float shutter) - { - motion_blur_shutter_ = shutter; - } - - virtual void calculate_corners(const float corners[4][2], bool normalized, int sample); - - private: - friend class PlaneTrackCommon; -}; - -class PlaneDistortWarpImageOperation : public PlaneDistortBaseOperation { - public: - PlaneDistortWarpImageOperation(); - - void calculate_corners(const float corners[4][2], bool normalized, int sample) override; - - 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 inputs) override; -}; - -class PlaneDistortMaskOperation : public PlaneDistortBaseOperation { - public: - PlaneDistortMaskOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc deleted file mode 100644 index eb6316d4b78..00000000000 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PlaneTrackOperation.h" - -#include "DNA_defaults.h" - -#include "BKE_movieclip.h" -#include "BKE_tracking.h" - -namespace blender::compositor { - -/* ******** PlaneTrackCommon ******** */ - -PlaneTrackCommon::PlaneTrackCommon() -{ - movie_clip_ = nullptr; - framenumber_ = 0; - tracking_object_name_[0] = '\0'; - plane_track_name_[0] = '\0'; -} - -void PlaneTrackCommon::read_and_calculate_corners(PlaneDistortBaseOperation *distort_op) -{ - float corners[4][2]; - if (distort_op->motion_blur_samples_ == 1) { - read_corners_from_track(corners, framenumber_); - distort_op->calculate_corners(corners, true, 0); - } - else { - const float frame = float(framenumber_) - distort_op->motion_blur_shutter_; - const float frame_step = (distort_op->motion_blur_shutter_ * 2.0f) / - distort_op->motion_blur_samples_; - float frame_iter = frame; - for (int sample = 0; sample < distort_op->motion_blur_samples_; sample++) { - read_corners_from_track(corners, frame_iter); - distort_op->calculate_corners(corners, true, sample); - frame_iter += frame_step; - } - } -} - -void PlaneTrackCommon::read_corners_from_track(float corners[4][2], float frame) -{ - if (!movie_clip_) { - return; - } - - MovieTracking *tracking = &movie_clip_->tracking; - - MovieTrackingObject *tracking_object = BKE_tracking_object_get_named(tracking, - tracking_object_name_); - if (tracking_object) { - MovieTrackingPlaneTrack *plane_track; - plane_track = BKE_tracking_object_find_plane_track_with_name(tracking_object, - plane_track_name_); - if (plane_track) { - float clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, frame); - BKE_tracking_plane_marker_get_subframe_corners(plane_track, clip_framenr, corners); - } - } -} - -void PlaneTrackCommon::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = COM_AREA_NONE; - if (movie_clip_) { - int width, height; - MovieClipUser user = *DNA_struct_default_get(MovieClipUser); - BKE_movieclip_user_set_frame(&user, framenumber_); - BKE_movieclip_get_size(movie_clip_, &user, &width, &height); - r_area = preferred_area; - r_area.xmax = r_area.xmin + width; - r_area.ymax = r_area.ymin + height; - } -} - -/* ******** PlaneTrackMaskOperation ******** */ - -void PlaneTrackMaskOperation::init_data() -{ - PlaneDistortMaskOperation::init_data(); - PlaneTrackCommon::read_and_calculate_corners(this); -} - -/* ******** PlaneTrackWarpImageOperation ******** */ - -void PlaneTrackWarpImageOperation::init_data() -{ - PlaneDistortWarpImageOperation::init_data(); - PlaneTrackCommon::read_and_calculate_corners(this); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h deleted file mode 100644 index da07a7ab340..00000000000 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_PlaneDistortCommonOperation.h" - -#include "DNA_movieclip_types.h" -#include "DNA_tracking_types.h" - -namespace blender::compositor { - -class PlaneTrackCommon { - protected: - MovieClip *movie_clip_; - int framenumber_; - char tracking_object_name_[64]; - char plane_track_name_[64]; - - /* NOTE: this class is not an operation itself (to prevent virtual inheritance issues) - * implementation classes must make wrappers to use these methods, see below. - */ - void read_and_calculate_corners(PlaneDistortBaseOperation *distort_op); - void determine_canvas(const rcti &preferred_area, rcti &r_area); - - public: - PlaneTrackCommon(); - - void set_movie_clip(MovieClip *clip) - { - movie_clip_ = clip; - } - void set_tracking_object(char *object) - { - BLI_strncpy(tracking_object_name_, object, sizeof(tracking_object_name_)); - } - void set_plane_track_name(char *plane_track) - { - BLI_strncpy(plane_track_name_, plane_track, sizeof(plane_track_name_)); - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - - private: - void read_corners_from_track(float corners[4][2], float frame); -}; - -class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTrackCommon { - public: - PlaneTrackMaskOperation() {} - - void init_data() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override - { - PlaneTrackCommon::determine_canvas(preferred_area, r_area); - - rcti unused = COM_AREA_NONE; - rcti &preferred = r_area; - NodeOperation::determine_canvas(preferred, unused); - } -}; - -class PlaneTrackWarpImageOperation : public PlaneDistortWarpImageOperation, - public PlaneTrackCommon { - public: - PlaneTrackWarpImageOperation() : PlaneTrackCommon() {} - - void init_data() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override - { - PlaneTrackCommon::determine_canvas(preferred_area, r_area); - - rcti unused = COM_AREA_NONE; - rcti &preferred = r_area; - NodeOperation::determine_canvas(preferred, unused); - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PosterizeOperation.cc b/source/blender/compositor/operations/COM_PosterizeOperation.cc deleted file mode 100644 index 51c246b0274..00000000000 --- a/source/blender/compositor/operations/COM_PosterizeOperation.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PosterizeOperation.h" - -namespace blender::compositor { - -PosterizeOperation::PosterizeOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void PosterizeOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *in_value = it.in(0); - const float *in_steps = it.in(1); - float steps = in_steps[0]; - CLAMP(steps, 2.0f, 1024.0f); - const float steps_inv = 1.0f / steps; - - it.out[0] = floor(in_value[0] / steps_inv) * steps_inv; - it.out[1] = floor(in_value[1] / steps_inv) * steps_inv; - it.out[2] = floor(in_value[2] / steps_inv) * steps_inv; - it.out[3] = in_value[3]; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PosterizeOperation.h b/source/blender/compositor/operations/COM_PosterizeOperation.h deleted file mode 100644 index d2cfbf809be..00000000000 --- a/source/blender/compositor/operations/COM_PosterizeOperation.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class PosterizeOperation : public MultiThreadedOperation { - public: - PosterizeOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cc b/source/blender/compositor/operations/COM_PreviewOperation.cc deleted file mode 100644 index 666dde2fac1..00000000000 --- a/source/blender/compositor/operations/COM_PreviewOperation.cc +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_PreviewOperation.h" - -#include "BKE_node.hh" -#include "IMB_colormanagement.hh" -#include "IMB_imbuf.hh" - -namespace blender::compositor { - -PreviewOperation::PreviewOperation(const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const uint default_width, - const uint default_height) - -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - preview_ = nullptr; - output_image_ = nullptr; - divider_ = 1.0f; - view_settings_ = view_settings; - display_settings_ = display_settings; - default_width_ = default_width; - default_height_ = default_height; - flags_.use_viewer_border = true; - flags_.is_preview_operation = true; -} - -void PreviewOperation::verify_preview(bke::bNodeInstanceHash *previews, bNodeInstanceKey key) -{ - /* Size (0, 0) ensures the preview rect is not allocated in advance, - * this is set later in init_execution once the resolution is determined. - */ - preview_ = blender::bke::node_preview_verify(previews, key, 0, 0, true); -} - -void PreviewOperation::init_execution() -{ - output_image_ = preview_->ibuf; - - if (this->get_width() == uint(preview_->ibuf->x) && - this->get_height() == uint(preview_->ibuf->y)) - { - return; - } - const uint size[2] = {get_width(), get_height()}; - IMB_rect_size_set(output_image_, size); - if (output_image_->byte_buffer.data == nullptr) { - imb_addrectImBuf(output_image_); - } -} - -void PreviewOperation::deinit_execution() -{ - output_image_ = nullptr; -} - -void PreviewOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - /* Use default preview resolution as preferred ensuring it has size so that - * generated inputs (which don't have resolution on their own) are displayed */ - BLI_assert(default_width_ > 0 && default_height_ > 0); - rcti local_preferred; - BLI_rcti_init(&local_preferred, 0, default_width_, 0, default_height_); - NodeOperation::determine_canvas(local_preferred, r_area); - - /* If resolution is 0 there are two possible scenarios: - * - Either node is not connected at all - * - Or it is connected to an input which has no resolution. - * - * In the former case we rely on the execution system to not evaluate this node. - * - * The latter case would only happen if an input doesn't set any resolution ignoring output - * preferred resolution. In such case preview size will be 0 too. - */ - int width = BLI_rcti_size_x(&r_area); - int height = BLI_rcti_size_y(&r_area); - divider_ = 0.0f; - if (width > 0 && height > 0) { - if (width > height) { - divider_ = float(COM_PREVIEW_SIZE) / (width); - } - else { - divider_ = float(COM_PREVIEW_SIZE) / (height); - } - } - width = width * divider_; - height = height * divider_; - - BLI_rcti_init(&r_area, r_area.xmin, r_area.xmin + width, r_area.ymin, r_area.ymin + height); -} - -eCompositorPriority PreviewOperation::get_render_priority() const -{ - return eCompositorPriority::Low; -} - -void PreviewOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - - r_input_area.xmin = output_area.xmin / divider_; - r_input_area.xmax = output_area.xmax / divider_; - r_input_area.ymin = output_area.ymin / divider_; - r_input_area.ymax = output_area.ymax / divider_; -} - -void PreviewOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input = inputs[0]; - ColormanageProcessor *cm_processor = IMB_colormanagement_display_processor_new( - view_settings_, display_settings_); - - rcti buffer_area; - BLI_rcti_init(&buffer_area, 0, this->get_width(), 0, this->get_height()); - BuffersIteratorBuilder it_builder(output_image_->byte_buffer.data, - buffer_area, - area, - COM_data_type_num_channels(DataType::Color)); - - for (BuffersIterator it = it_builder.build(); !it.is_end(); ++it) { - const float rx = it.x / divider_; - const float ry = it.y / divider_; - - float color[4]; - input->read_elem_checked(rx, ry, color); - IMB_colormanagement_processor_apply_v4(cm_processor, color); - rgba_float_to_uchar(it.out, color); - } - - IMB_colormanagement_processor_free(cm_processor); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h deleted file mode 100644 index 2e460ba5381..00000000000 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BKE_global.hh" -#include "BLI_rect.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_color_types.h" -#include "DNA_image_types.h" - -namespace blender::compositor { - -class PreviewOperation : public MultiThreadedOperation { - protected: - ImBuf *output_image_; - - /** - * \brief holds reference to the SDNA bNode, where this nodes will render the preview image for - */ - bNodePreview *preview_; - float divider_; - unsigned int default_width_; - unsigned int default_height_; - - const ColorManagedViewSettings *view_settings_; - const ColorManagedDisplaySettings *display_settings_; - - public: - PreviewOperation(const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - unsigned int default_width, - unsigned int default_height); - void verify_preview(bke::bNodeInstanceHash *previews, bNodeInstanceKey key); - - bool is_output_operation(bool /*rendering*/) const override - { - return !G.background; - } - void init_execution() override; - void deinit_execution() override; - eCompositorPriority get_render_priority() const override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc deleted file mode 100644 index 7eecd4e8fea..00000000000 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ProjectorLensDistortionOperation.h" -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -ProjectorLensDistortionOperation::ProjectorLensDistortionOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; - dispersion_ = 0.0f; -} - -void ProjectorLensDistortionOperation::init_data() -{ - NodeOperation *dispersion_input = get_input_operation(1); - if (dispersion_input->get_flags().is_constant_operation) { - dispersion_ = static_cast(dispersion_input)->get_constant_elem()[0]; - } - kr_ = 0.25f * max_ff(min_ff(dispersion_, 1.0f), 0.0f); - kr2_ = kr_ * 20; -} - -void ProjectorLensDistortionOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - set_determined_canvas_modifier([=](rcti &canvas) { - /* Ensure screen space. */ - BLI_rcti_translate(&canvas, -canvas.xmin, -canvas.ymin); - }); - - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void ProjectorLensDistortionOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx == 1) { - /* Dispersion input is used as constant only. */ - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - return; - } - - r_input_area.ymax = output_area.ymax; - r_input_area.ymin = output_area.ymin; - r_input_area.xmin = output_area.xmin - kr2_ - 2; - r_input_area.xmax = output_area.xmax + kr2_ + 2; -} - -void ProjectorLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_image = inputs[0]; - const float height = this->get_height(); - const float width = this->get_width(); - float color[4]; - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - const float v = (it.y + 0.5f) / height; - const float u = (it.x + 0.5f) / width; - input_image->read_elem_bilinear((u * width + kr2_) - 0.5f, v * height - 0.5f, color); - it.out[0] = color[0]; - input_image->read_elem(it.x, it.y, color); - it.out[1] = color[1]; - input_image->read_elem_bilinear((u * width - kr2_) - 0.5f, v * height - 0.5f, color); - it.out[2] = color[2]; - it.out[3] = 1.0f; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h deleted file mode 100644 index c0ab16b2b18..00000000000 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class ProjectorLensDistortionOperation : public MultiThreadedOperation { - private: - float dispersion_; - - float kr_, kr2_; - - public: - ProjectorLensDistortionOperation(); - - void init_data() override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - 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 inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cc b/source/blender/compositor/operations/COM_RenderLayersProg.cc deleted file mode 100644 index 44ed0b70888..00000000000 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cc +++ /dev/null @@ -1,205 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_RenderLayersProg.h" - -#include "BLI_math_interp.hh" -#include "BLI_string.h" - -#include "BKE_image.hh" - -namespace blender::compositor { - -/* ******** Render Layers Base Prog ******** */ - -RenderLayersProg::RenderLayersProg(const char *pass_name, DataType type, int elementsize) - : pass_name_(pass_name) -{ - this->set_scene(nullptr); - input_buffer_ = nullptr; - elementsize_ = elementsize; - rd_ = nullptr; - layer_buffer_ = nullptr; - - this->add_output_socket(type); -} - -void RenderLayersProg::init_execution() -{ - Scene *scene = this->get_scene(); - Render *re = (scene) ? RE_GetSceneRender(scene) : nullptr; - RenderResult *rr = nullptr; - - if (re) { - rr = RE_AcquireResultRead(re); - } - - if (rr) { - ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, get_layer_id()); - if (view_layer) { - - RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name); - if (rl) { - input_buffer_ = RE_RenderLayerGetPass(rl, pass_name_.c_str(), view_name_); - if (input_buffer_) { - layer_buffer_ = new MemoryBuffer(input_buffer_, elementsize_, get_width(), get_height()); - } - } - } - } - if (re) { - RE_ReleaseResult(re); - re = nullptr; - } -} - -void RenderLayersProg::deinit_execution() -{ - input_buffer_ = nullptr; - if (layer_buffer_) { - delete layer_buffer_; - layer_buffer_ = nullptr; - } -} - -void RenderLayersProg::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) -{ - Scene *sce = this->get_scene(); - Render *re = (sce) ? RE_GetSceneRender(sce) : nullptr; - RenderResult *rr = nullptr; - - r_area = COM_AREA_NONE; - - if (re) { - rr = RE_AcquireResultRead(re); - } - - if (rr) { - ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&sce->view_layers, get_layer_id()); - if (view_layer) { - RenderLayer *rl = RE_GetRenderLayer(rr, view_layer->name); - if (rl) { - BLI_rcti_init(&r_area, 0, rl->rectx, 0, rl->recty); - } - } - } - - if (re) { - RE_ReleaseResult(re); - } -} - -std::unique_ptr RenderLayersProg::get_meta_data() -{ - Scene *scene = this->get_scene(); - Render *re = (scene) ? RE_GetSceneRender(scene) : nullptr; - RenderResult *render_result = nullptr; - MetaDataExtractCallbackData callback_data = {std::make_unique()}; - - if (re) { - render_result = RE_AcquireResultRead(re); - } - - if (render_result && render_result->stamp_data) { - ViewLayer *view_layer = (ViewLayer *)BLI_findlink(&scene->view_layers, get_layer_id()); - if (view_layer) { - std::string full_layer_name = std::string( - view_layer->name, - BLI_strnlen(view_layer->name, sizeof(view_layer->name))) + - "." + pass_name_; - blender::StringRef cryptomatte_layer_name = - blender::bke::cryptomatte::BKE_cryptomatte_extract_layer_name(full_layer_name); - callback_data.set_cryptomatte_keys(cryptomatte_layer_name); - - BKE_stamp_info_callback(&callback_data, - render_result->stamp_data, - MetaDataExtractCallbackData::extract_cryptomatte_meta_data, - false); - - RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name); - if (render_layer) { - RenderPass *render_pass = RE_pass_find_by_name( - render_layer, pass_name_.c_str(), view_name_); - if (render_pass) { - if (StringRef(render_pass->chan_id) == "XYZW") { - callback_data.meta_data->is_4d_vector = true; - } - } - } - } - } - - if (re) { - RE_ReleaseResult(re); - re = nullptr; - } - - return std::move(callback_data.meta_data); -} - -void RenderLayersProg::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - BLI_assert(output->get_num_channels() >= elementsize_); - if (layer_buffer_) { - output->copy_from(layer_buffer_, area, 0, elementsize_, 0); - } - else { - std::unique_ptr zero_elem = std::make_unique(elementsize_); - output->fill(area, 0, zero_elem.get(), elementsize_); - } -} - -/* ******** Render Layers AO Operation ******** */ - -void RenderLayersAOOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - BLI_assert(output->get_num_channels() == COM_DATA_TYPE_COLOR_CHANNELS); - BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS); - if (layer_buffer_) { - output->copy_from(layer_buffer_, area, 0, COM_DATA_TYPE_VECTOR_CHANNELS, 0); - } - else { - output->fill(area, 0, COM_VECTOR_ZERO, COM_DATA_TYPE_VECTOR_CHANNELS); - } - output->fill(area, 3, COM_VALUE_ONE, COM_DATA_TYPE_VALUE_CHANNELS); -} - -/* ******** Render Layers Alpha Operation ******** */ - -void RenderLayersAlphaProg::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); - BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS); - if (layer_buffer_) { - output->copy_from(layer_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); - } - else { - output->fill(area, COM_VALUE_ZERO); - } -} - -/* ******** Render Layers Depth Operation ******** */ - -void RenderLayersDepthProg::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span /*inputs*/) -{ - BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); - BLI_assert(elementsize_ == COM_DATA_TYPE_VALUE_CHANNELS); - if (layer_buffer_) { - output->copy_from(layer_buffer_, area); - } - else { - const float default_depth = 10e10f; - output->fill(area, &default_depth); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h deleted file mode 100644 index b874f471289..00000000000 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_listbase.h" -#include "BLI_utildefines.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_scene_types.h" -#include "MEM_guardedalloc.h" - -#include "RE_pipeline.h" - -namespace blender::compositor { - -/** - * Base class for all renderlayeroperations - * - * \todo Rename to operation. - */ -class RenderLayersProg : public MultiThreadedOperation { - protected: - /** - * Reference to the scene object. - */ - Scene *scene_; - - /** - * layer_id of the layer where this operation needs to get its data from - */ - short layer_id_; - - /** - * view_name of the view to use (unless another view is specified by the node - */ - const char *view_name_; - - const MemoryBuffer *layer_buffer_; - - /** - * Cached instance to the float buffer inside the layer. - * TODO: To be removed with tiled implementation. - */ - float *input_buffer_; - - /** - * Render-pass where this operation needs to get its data from. - */ - std::string pass_name_; - - int elementsize_; - - /** - * \brief render data used for active rendering - */ - const RenderData *rd_; - - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - /** - * retrieve the reference to the float buffer of the renderer. - */ - inline float *get_input_buffer() - { - return input_buffer_; - } - - public: - /** - * Constructor - */ - RenderLayersProg(const char *pass_name, DataType type, int elementsize); - /** - * setter for the scene field. Will be called from - * \see RenderLayerNode to set the actual scene where - * the data will be retrieved from. - */ - void set_scene(Scene *scene) - { - scene_ = scene; - } - Scene *get_scene() const - { - return scene_; - } - void set_render_data(const RenderData *rd) - { - rd_ = rd; - } - void set_layer_id(short layer_id) - { - layer_id_ = layer_id; - } - short get_layer_id() const - { - return layer_id_; - } - void set_view_name(const char *view_name) - { - view_name_ = view_name; - } - const char *get_view_name() - { - return view_name_; - } - void init_execution() override; - void deinit_execution() override; - - std::unique_ptr get_meta_data() override; - - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class RenderLayersAOOperation : public RenderLayersProg { - public: - RenderLayersAOOperation(const char *pass_name, DataType type, int elementsize) - : RenderLayersProg(pass_name, type, elementsize) - { - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class RenderLayersAlphaProg : public RenderLayersProg { - public: - RenderLayersAlphaProg(const char *pass_name, DataType type, int elementsize) - : RenderLayersProg(pass_name, type, elementsize) - { - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class RenderLayersDepthProg : public RenderLayersProg { - public: - RenderLayersDepthProg(const char *pass_name, DataType type, int elementsize) - : RenderLayersProg(pass_name, type, elementsize) - { - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc deleted file mode 100644 index 23547c5a52c..00000000000 --- a/source/blender/compositor/operations/COM_RotateOperation.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_RotateOperation.h" - -#include "BLI_math_rotation.h" - -namespace blender::compositor { - -RotateOperation::RotateOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::None); - this->add_input_socket(DataType::Value, ResizeMode::None); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - do_degree2_rad_conversion_ = false; - is_degree_set_ = false; - sampler_ = PixelSampler::Bilinear; - flags_.can_be_constant = true; -} - -void RotateOperation::get_rotation_center(const rcti &area, float &r_x, float &r_y) -{ - r_x = BLI_rcti_size_x(&area) / 2.0; - r_y = BLI_rcti_size_y(&area) / 2.0; -} - -void RotateOperation::get_rotation_offset(const rcti &input_canvas, - const rcti &rotate_canvas, - float &r_offset_x, - float &r_offset_y) -{ - r_offset_x = (BLI_rcti_size_x(&input_canvas) - BLI_rcti_size_x(&rotate_canvas)) / 2.0f; - r_offset_y = (BLI_rcti_size_y(&input_canvas) - BLI_rcti_size_y(&rotate_canvas)) / 2.0f; -} - -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 = std::min(x1, std::min(x2, std::min(x3, x4))); - const float maxx = std::max(x1, std::max(x2, std::max(x3, x4))); - const float miny = std::min(y1, std::min(y2, std::min(y3, y4))); - const float maxy = std::max(y1, std::max(y2, std::max(y3, y4))); - - r_bounds.xmin = floor(minx); - r_bounds.xmax = ceil(maxx); - r_bounds.ymin = floor(miny); - r_bounds.ymax = ceil(maxy); -} - -void RotateOperation::get_area_rotation_bounds_inverted(const rcti &area, - const float center_x, - const float center_y, - const float sine, - const float cosine, - rcti &r_bounds) -{ - get_area_rotation_bounds(area, center_x, center_y, -sine, cosine, r_bounds); -} - -void RotateOperation::get_rotation_area_of_interest(const rcti &input_canvas, - const rcti &rotate_canvas, - const float sine, - const float cosine, - const rcti &output_area, - rcti &r_input_area) -{ - float center_x, center_y; - get_rotation_center(input_canvas, center_x, center_y); - - float rotate_offset_x, rotate_offset_y; - get_rotation_offset(input_canvas, rotate_canvas, rotate_offset_x, rotate_offset_y); - - r_input_area = output_area; - BLI_rcti_translate(&r_input_area, rotate_offset_x, rotate_offset_y); - get_area_rotation_bounds_inverted(r_input_area, center_x, center_y, sine, cosine, r_input_area); -} - -void RotateOperation::get_rotation_canvas(const rcti &input_canvas, - const float sine, - const float cosine, - rcti &r_canvas) -{ - float center_x, center_y; - get_rotation_center(input_canvas, center_x, center_y); - - rcti rot_bounds; - get_area_rotation_bounds(input_canvas, center_x, center_y, sine, cosine, rot_bounds); - - float offset_x, offset_y; - get_rotation_offset(input_canvas, rot_bounds, offset_x, offset_y); - r_canvas = rot_bounds; - BLI_rcti_translate(&r_canvas, -offset_x, -offset_y); -} - -void RotateOperation::init_data() {} - -inline void RotateOperation::ensure_degree() -{ - if (!is_degree_set_) { - float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f); - - double rad; - if (do_degree2_rad_conversion_) { - rad = DEG2RAD(double(degree)); - } - else { - rad = degree; - } - cosine_ = cos(rad); - sine_ = sin(rad); - - is_degree_set_ = true; - } -} - -void RotateOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - const bool image_determined = - get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area); - if (image_determined) { - rcti input_canvas = r_area; - rcti unused = COM_AREA_NONE; - get_input_socket(DEGREE_INPUT_INDEX)->determine_canvas(input_canvas, unused); - - ensure_degree(); - - get_rotation_canvas(input_canvas, sine_, cosine_, r_area); - } -} - -void RotateOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx == DEGREE_INPUT_INDEX) { - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - return; - } - - ensure_degree(); - - const rcti &input_image_canvas = get_input_operation(IMAGE_INPUT_INDEX)->get_canvas(); - get_rotation_area_of_interest( - input_image_canvas, this->get_canvas(), sine_, cosine_, output_area, r_input_area); - expand_area_for_sampler(r_input_area, sampler_); -} - -void RotateOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[IMAGE_INPUT_INDEX]; - - NodeOperation *image_op = get_input_operation(IMAGE_INPUT_INDEX); - float center_x, center_y; - get_rotation_center(image_op->get_canvas(), center_x, center_y); - float rotate_offset_x, rotate_offset_y; - get_rotation_offset( - image_op->get_canvas(), this->get_canvas(), rotate_offset_x, rotate_offset_y); - - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float x = rotate_offset_x + it.x + canvas_.xmin + 0.5f; - float y = rotate_offset_y + it.y + canvas_.ymin + 0.5f; - rotate_coords(x, y, center_x, center_y, sine_, cosine_); - input_img->read_elem_sampled( - x - canvas_.xmin - 0.5f, y - canvas_.ymin - 0.5f, sampler_, it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h deleted file mode 100644 index 536153e3f9a..00000000000 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class RotateOperation : public MultiThreadedOperation { - private: - constexpr static int IMAGE_INPUT_INDEX = 0; - constexpr static int DEGREE_INPUT_INDEX = 1; - - float cosine_; - float sine_; - bool do_degree2_rad_conversion_; - bool is_degree_set_; - PixelSampler sampler_; - - 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 = center_x + (cosine * dx + sine * dy); - y = center_y + (-sine * dx + cosine * dy); - } - - static void get_rotation_center(const rcti &area, float &r_x, float &r_y); - static void get_rotation_offset(const rcti &input_canvas, - const rcti &rotate_canvas, - float &r_offset_x, - float &r_offset_y); - static void get_area_rotation_bounds( - const rcti &area, float center_x, float center_y, float sine, float cosine, rcti &r_bounds); - static void get_area_rotation_bounds_inverted( - const rcti &area, float center_x, float center_y, float sine, float cosine, rcti &r_bounds); - static void get_rotation_area_of_interest(const rcti &input_canvas, - const rcti &rotate_canvas, - float sine, - float cosine, - const rcti &output_area, - rcti &r_input_area); - static void get_rotation_canvas(const rcti &input_canvas, - float sine, - float cosine, - rcti &r_canvas); - - void init_data() override; - - void set_do_degree2_rad_conversion(bool abool) - { - do_degree2_rad_conversion_ = abool; - } - - void set_sampler(PixelSampler sampler) - { - sampler_ = sampler; - } - - void ensure_degree(); - - 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 inputs) override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc deleted file mode 100644 index bd72b2aa98e..00000000000 --- a/source/blender/compositor/operations/COM_SMAAOperation.cc +++ /dev/null @@ -1,1512 +0,0 @@ -/* SPDX-FileCopyrightText: 2013 Jorge Jimenez - * SPDX-FileCopyrightText: 2013 Jose I. Echevarria - * SPDX-FileCopyrightText: 2013 Belen Masia - * SPDX-FileCopyrightText: 2013 Fernando Navarro - * SPDX-FileCopyrightText: 2013 Diego Gutierrez - * SPDX-FileCopyrightText: 2019-2023 Blender Authors - * - * SPDX-License-Identifier: MIT AND GPL-2.0-or-later */ - -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_smaa_textures.h" -#include "BLI_span.hh" -#include "BLI_task.hh" - -#include "IMB_colormanagement.hh" - -#include "COM_MemoryBuffer.h" -#include "COM_SMAAOperation.h" - -/** - * _______ ___ ___ ___ ___ - * / || \/ | / \ / \ - * | (---- | \ / | / ^ \ / ^ \ - * \ \ | |\/| | / /_\ \ / /_\ \ - * ----) | | | | | / _____ \ / _____ \ - * |_______/ |__| |__| /__/ \__\ /__/ \__\ - * - * E N H A N C E D - * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G - * - * http://www.iryoku.com/smaa/ - * - * Hi, welcome aboard! - * - * Here you'll find instructions to get the shader up and running as fast as - * possible. - * - * IMPORTANTE NOTICE: when updating, remember to update both this file and the - * precomputed textures! They may change from version to version. - * - * The shader has three passes, chained together as follows: - * - * |input|------------------� - * v | - * [ SMAA*EdgeDetection ] | - * v | - * |edgesTex| | - * v | - * [ SMAABlendingWeightCalculation ] | - * v | - * |blendTex| | - * v | - * [ SMAANeighborhoodBlending ] <------� - * v - * |output| - * - * Note that each [pass] has its own vertex and pixel shader. Remember to use - * over-sized triangles instead of quads to avoid over-shading along the - * diagonal. - * - * You've three edge detection methods to choose from: luma, color or depth. - * They represent different quality/performance and anti-aliasing/sharpness - * tradeoffs, so our recommendation is for you to choose the one that best - * suits your particular scenario: - * - * - Depth edge detection is usually the fastest but it may miss some edges. - * - * - Luma edge detection is usually more expensive than depth edge detection, - * but catches visible edges that depth edge detection can miss. - * - * - Color edge detection is usually the most expensive one but catches - * chroma-only edges. - * - * For quick-starters: just use luma edge detection. - * - * The general advice is to not rush the integration process and ensure each - * step is done correctly (don't try to integrate SMAA T2x with predicated edge - * detection from the start!). Ok then, let's go! - * - * 1. The first step is to create two RGBA temporal render targets for holding - * |edgesTex| and |blendTex|. - * - * In DX10 or DX11, you can use a RG render target for the edges texture. - * In the case of NVIDIA GPUs, using RG render targets seems to actually be - * slower. - * - * On the Xbox 360, you can use the same render target for resolving both - * |edgesTex| and |blendTex|, as they aren't needed simultaneously. - * - * 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared - * each frame. Do not forget to clear the alpha channel! - * - * 3. The next step is loading the two supporting precalculated textures, - * 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as - * C++ headers, and also as regular DDS files. They'll be needed for the - * 'SMAABlendingWeightCalculation' pass. - * - * If you use the C++ headers, be sure to load them in the format specified - * inside of them. - * - * You can also compress 'areaTex' and 'searchTex' using BC5 and BC4 - * respectively, if you have that option in your content processor pipeline. - * When compressing then, you get a non-perceptible quality decrease, and a - * marginal performance increase. - * - * 4. All samplers must be set to linear filtering and clamp. - * - * After you get the technique working, remember that 64-bit inputs have - * half-rate linear filtering on GCN. - * - * If SMAA is applied to 64-bit color buffers, switching to point filtering - * when accessing them will increase the performance. Search for - * 'SMAASamplePoint' to see which textures may benefit from point - * filtering, and where (which is basically the color input in the edge - * detection and resolve passes). - * - * 5. All texture reads and buffer writes must be non-sRGB, with the exception - * of the input read and the output write in - * 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in - * this last pass are not possible, the technique will work anyway, but - * will perform anti-aliasing in gamma space. - * - * IMPORTANT: for best results the input read for the color/luma edge - * detection should *NOT* be sRGB. - * - * 6. Before including SMAA.h you'll have to setup the render target metrics, - * the target and any optional configuration defines. Optionally you can - * use a preset. - * - * You have the following targets available: - * SMAA_HLSL_3 - * SMAA_HLSL_4 - * SMAA_HLSL_4_1 - * SMAA_GLSL_3 * - * SMAA_GLSL_4 * - * - * * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below). - * - * And four presets: - * SMAA_PRESET_LOW (%60 of the quality) - * SMAA_PRESET_MEDIUM (%80 of the quality) - * SMAA_PRESET_HIGH (%95 of the quality) - * SMAA_PRESET_ULTRA (%99 of the quality) - * - * For example: - * #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0) - * #define SMAA_HLSL_4 - * #define SMAA_PRESET_HIGH - * #include "SMAA.h" - * - * Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a - * uniform variable. The code is designed to minimize the impact of not - * using a constant value, but it is still better to hard-code it. - * - * Depending on how you encoded 'areaTex' and 'searchTex', you may have to - * add (and customize) the following defines before including SMAA.h: - * #define SMAA_AREATEX_SELECT(sample) sample.rg - * #define SMAA_SEARCHTEX_SELECT(sample) sample.r - * - * If your engine is already using porting macros, you can define - * SMAA_CUSTOM_SL, and define the porting functions by yourself. - * - * 7. Then, you'll have to setup the passes as indicated in the scheme above. - * You can take a look into SMAA.fx, to see how we did it for our demo. - * Checkout the function wrappers, you may want to copy-paste them! - * - * 8. It's recommended to validate the produced |edgesTex| and |blendTex|. - * You can use a screenshot from your engine to compare the |edgesTex| - * and |blendTex| produced inside of the engine with the results obtained - * with the reference demo. - * - * 9. After you get the last pass to work, it's time to optimize. You'll have - * to initialize a stencil buffer in the first pass (discard is already in - * the code), then mask execution by using it the second pass. The last - * pass should be executed in all pixels. - * - * - * After this point you can choose to enable predicated thresholding, - * temporal supersampling and motion blur integration: - * - * a) If you want to use predicated thresholding, take a look into - * SMAA_PREDICATION; you'll need to pass an extra texture in the edge - * detection pass. - * - * b) If you want to enable temporal supersampling (SMAA T2x): - * - * 1. The first step is to render using sub-pixel jitters. I won't go into - * detail, but it's as simple as moving each vertex position in the - * vertex shader, you can check how we do it in our DX10 demo. - * - * 2. Then, you must setup the temporal resolve. You may want to take a look - * into SMAAResolve for resolving 2x modes. After you get it working, you'll - * probably see ghosting everywhere. But fear not, you can enable the - * CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro. - * Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded. - * - * 3. The next step is to apply SMAA to each sub-pixel jittered frame, just as - * done for 1x. - * - * 4. At this point you should already have something usable, but for best - * results the proper area textures must be set depending on current jitter. - * For this, the parameter 'subsampleIndices' of - * 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x - * mode: - * - * @SUBSAMPLE_INDICES - * - * | S# | Camera Jitter | subsampleIndices | - * +----+------------------+---------------------+ - * | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) | - * | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) | - * - * These jitter positions assume a bottom-to-top y axis. S# stands for the - * sample number. - * - * More information about temporal supersampling here: - * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf - * - * c) If you want to enable spatial multisampling (SMAA S2x): - * - * 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be - * created with: - * - DX10: see below (*) - * - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or - * - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN - * - * This allows to ensure that the subsample order matches the table in - * @SUBSAMPLE_INDICES. - * - * (*) In the case of DX10, we refer the reader to: - * - SMAA::detectMSAAOrder and - * - SMAA::msaaReorder - * - * These functions allow matching the standard multisample patterns by - * detecting the subsample order for a specific GPU, and reordering - * them appropriately. - * - * 2. A shader must be run to output each subsample into a separate buffer - * (DX10 is required). You can use SMAASeparate for this purpose, or just do - * it in an existing pass (for example, in the tone mapping pass, which has - * the advantage of feeding tone mapped subsamples to SMAA, which will yield - * better results). - * - * 3. The full SMAA 1x pipeline must be run for each separated buffer, storing - * the results in the final buffer. The second run should alpha blend with - * the existing final buffer using a blending factor of 0.5. - * 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point - * b). - * - * d) If you want to enable temporal supersampling on top of SMAA S2x - * (which actually is SMAA 4x): - * - * 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is - * to calculate SMAA S2x for current frame. In this case, 'subsampleIndices' - * must be set as follows: - * - * | F# | S# | Camera Jitter | Net Jitter | subsampleIndices | - * +----+----+--------------------+-------------------+----------------------+ - * | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) | - * | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) | - * +----+----+--------------------+-------------------+----------------------+ - * | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) | - * | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) | - * - * These jitter positions assume a bottom-to-top y axis. F# stands for the - * frame number. S# stands for the sample number. - * - * 2. After calculating SMAA S2x for current frame (with the new subsample - * indices), previous frame must be reprojected as in SMAA T2x mode (see - * point b). - * - * e) If motion blur is used, you may want to do the edge detection pass - * together with motion blur. This has two advantages: - * - * 1. Pixels under heavy motion can be omitted from the edge detection process. - * For these pixels we can just store "no edge", as motion blur will take - * care of them. - * 2. The center pixel tap is reused. - * - * Note that in this case depth testing should be used instead of stenciling, - * as we have to write all the pixels in the motion blur pass. - * - * That's it! - */ - -/* ---------------------------------------------------------------------------- - * Blender's Defines */ - -#define SMAA_CUSTOM_SL -#define SMAA_AREATEX_SELECT(sample) sample.xy() -#define SMAA_SEARCHTEX_SELECT(sample) sample.x -#define SMAATexture2D(tex) const MemoryBuffer *tex -#define SMAATexturePass2D(tex) tex -#define SMAASampleLevelZero(tex, coord) tex->texture_bilinear_extend(coord) -#define SMAASampleLevelZeroPoint(tex, coord) tex->texture_bilinear_extend(coord) -#define SMAASampleLevelZeroOffset(tex, coord, offset, size) \ - tex->texture_bilinear_extend(coord + float2(offset) / float2(size)) -#define SMAASample(tex, coord) tex->texture_bilinear_extend(coord) -#define SMAASamplePoint(tex, coord) tex->texture_nearest_extend(coord) -#define SMAASamplePointOffset(tex, coord, offset, size) \ - tex->texture_nearest_extend(coord + float2(offset) / float2(size)) -#define SMAASampleOffset(tex, coord, offset, size) \ - tex->texture_bilinear_extend(coord + float2(offset) / float2(size)) -#define SMAA_FLATTEN -#define SMAA_BRANCH -#define lerp(a, b, t) math::interpolate(a, b, t) -#define saturate(a) math::clamp(a, 0.0f, 1.0f) -#define mad(a, b, c) (a * b + c) - -/* ---------------------------------------------------------------------------- - * SMAA Presets */ - -/** - * Note that if you use one of these presets, the following configuration - * macros will be ignored if set in the "Configurable Defines" section. - */ - -#if defined(SMAA_PRESET_LOW) -# define SMAA_THRESHOLD 0.15f -# define SMAA_MAX_SEARCH_STEPS 4 -# define SMAA_DISABLE_DIAG_DETECTION -# define SMAA_DISABLE_CORNER_DETECTION -#elif defined(SMAA_PRESET_MEDIUM) -# define SMAA_THRESHOLD 0.1f -# define SMAA_MAX_SEARCH_STEPS 8 -# define SMAA_DISABLE_DIAG_DETECTION -# define SMAA_DISABLE_CORNER_DETECTION -#elif defined(SMAA_PRESET_HIGH) -# define SMAA_THRESHOLD 0.1f -# define SMAA_MAX_SEARCH_STEPS 16 -# define SMAA_MAX_SEARCH_STEPS_DIAG 8 -# define SMAA_CORNER_ROUNDING 25 -#elif defined(SMAA_PRESET_ULTRA) -# define SMAA_THRESHOLD 0.05f -# define SMAA_MAX_SEARCH_STEPS 32 -# define SMAA_MAX_SEARCH_STEPS_DIAG 16 -# define SMAA_CORNER_ROUNDING 25 -#endif - -/* ---------------------------------------------------------------------------- - * Configurable Defines */ - -/** - * SMAA_THRESHOLD specifies the threshold or sensitivity to edges. - * Lowering this value you will be able to detect more edges at the expense of - * performance. - * - * Range: [0, 0.5] - * 0.1 is a reasonable value, and allows to catch most visible edges. - * 0.05 is a rather overkill value, that allows to catch 'em all. - * - * If temporal supersampling is used, 0.2 could be a reasonable value, as low - * contrast edges are properly filtered by just 2x. - */ -#ifndef SMAA_THRESHOLD -# define SMAA_THRESHOLD 0.1f -#endif - -/** - * SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection. - * - * Range: depends on the depth range of the scene. - */ -#ifndef SMAA_DEPTH_THRESHOLD -# define SMAA_DEPTH_THRESHOLD (0.1f * SMAA_THRESHOLD) -#endif - -/** - * SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the - * horizontal/vertical pattern searches, at each side of the pixel. - * - * In number of pixels, it's actually the double. So the maximum line length - * perfectly handled by, for example 16, is 64 (by perfectly, we meant that - * longer lines won't look as good, but still anti-aliased). - * - * Range: [0, 112] - */ -#ifndef SMAA_MAX_SEARCH_STEPS -# define SMAA_MAX_SEARCH_STEPS 16 -#endif - -/** - * SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the - * diagonal pattern searches, at each side of the pixel. In this case we jump - * one pixel at time, instead of two. - * - * Range: [0, 20] - * - * On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16 - * steps), but it can have a significant impact on older machines. - * - * Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing. - */ -#ifndef SMAA_MAX_SEARCH_STEPS_DIAG -# define SMAA_MAX_SEARCH_STEPS_DIAG 8 -#endif - -/** - * SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded. - * - * Range: [0, 100] - * - * Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing. - */ -#ifndef SMAA_CORNER_ROUNDING -# define SMAA_CORNER_ROUNDING 25 -#endif - -/** - * If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times - * bigger contrast than current edge, current edge will be discarded. - * - * This allows to eliminate spurious crossing edges, and is based on the fact - * that, if there is too much contrast in a direction, that will hide - * perceptually contrast in the other neighbors. - */ -#ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR -# define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0f -#endif - -/** - * Predicated thresholding allows to better preserve texture details and to - * improve performance, by decreasing the number of detected edges using an - * additional buffer like the light accumulation buffer, object ids or even the - * depth buffer (the depth buffer usage may be limited to indoor or short range - * scenes). - * - * It locally decreases the luma or color threshold if an edge is found in an - * additional buffer (so the global threshold can be higher). - * - * This method was developed by Playstation EDGE MLAA team, and used in - * Killzone 3, by using the light accumulation buffer. More information here: - * http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx - */ -#ifndef SMAA_PREDICATION -# define SMAA_PREDICATION 0 -#endif - -/** - * Threshold to be used in the additional predication buffer. - * - * Range: depends on the input, so you'll have to find the magic number that - * works for you. - */ -#ifndef SMAA_PREDICATION_THRESHOLD -# define SMAA_PREDICATION_THRESHOLD 0.01f -#endif - -/** - * How much to scale the global threshold used for luma or color edge - * detection when using predication. - * - * Range: [1, 5] - */ -#ifndef SMAA_PREDICATION_SCALE -# define SMAA_PREDICATION_SCALE 2.0f -#endif - -/** - * How much to locally decrease the threshold. - * - * Range: [0, 1] - */ -#ifndef SMAA_PREDICATION_STRENGTH -# define SMAA_PREDICATION_STRENGTH 0.4f -#endif - -/** - * Temporal reprojection allows to remove ghosting artifacts when using - * temporal supersampling. We use the CryEngine 3 method which also introduces - * velocity weighting. This feature is of extreme importance for totally - * removing ghosting. More information here: - * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf - * - * Note that you'll need to setup a velocity buffer for enabling reprojection. - * For static geometry, saving the previous depth buffer is a viable - * alternative. - */ -#ifndef SMAA_REPROJECTION -# define SMAA_REPROJECTION 0 -#endif - -/** - * SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to - * remove ghosting trails behind the moving object, which are not removed by - * just using reprojection. Using low values will exhibit ghosting, while using - * high values will disable temporal supersampling under motion. - * - * Behind the scenes, velocity weighting removes temporal supersampling when - * the velocity of the subsamples differs (meaning they are different objects). - * - * Range: [0, 80] - */ -#ifndef SMAA_REPROJECTION_WEIGHT_SCALE -# define SMAA_REPROJECTION_WEIGHT_SCALE 30.0f -#endif - -/** - * On some compilers, discard cannot be used in vertex shaders. Thus, they need - * to be compiled separately. - */ -#ifndef SMAA_INCLUDE_VS -# define SMAA_INCLUDE_VS 1 -#endif -#ifndef SMAA_INCLUDE_PS -# define SMAA_INCLUDE_PS 1 -#endif - -/* ---------------------------------------------------------------------------- - * Texture Access Defines */ - -#ifndef SMAA_AREATEX_SELECT -# if defined(SMAA_HLSL_3) -# define SMAA_AREATEX_SELECT(sample) sample.ra -# else -# define SMAA_AREATEX_SELECT(sample) sample.rg -# endif -#endif - -#ifndef SMAA_SEARCHTEX_SELECT -# define SMAA_SEARCHTEX_SELECT(sample) sample.r -#endif - -#ifndef SMAA_DECODE_VELOCITY -# define SMAA_DECODE_VELOCITY(sample) sample.rg -#endif - -/* ---------------------------------------------------------------------------- - * Non-Configurable Defines */ - -#define SMAA_AREATEX_MAX_DISTANCE 16 -#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 -#define SMAA_AREATEX_PIXEL_SIZE (1.0f / float2(160.0f, 560.0f)) -#define SMAA_AREATEX_SUBTEX_SIZE (1.0f / 7.0f) -#define SMAA_SEARCHTEX_SIZE float2(66.0f, 33.0f) -#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0f, 16.0f) -#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0f) - -/* ---------------------------------------------------------------------------- - * Porting Functions */ - -#if defined(SMAA_HLSL_3) -# define SMAATexture2D(tex) sampler2D tex -# define SMAATexturePass2D(tex) tex -# define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) -# define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) -/* clang-format off */ -# define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0)) -/* clang-format on */ -# define SMAASample(tex, coord) tex2D(tex, coord) -# define SMAASamplePoint(tex, coord) tex2D(tex, coord) -# define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy) -# define SMAA_FLATTEN [flatten] -# define SMAA_BRANCH [branch] -#endif -#if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1) -SamplerState LinearSampler -{ - Filter = MIN_MAG_LINEAR_MIP_POINT; - AddressU = Clamp; - AddressV = Clamp; -}; -SamplerState PointSampler -{ - Filter = MIN_MAG_MIP_POINT; - AddressU = Clamp; - AddressV = Clamp; -}; -# define SMAATexture2D(tex) Texture2D tex -# define SMAATexturePass2D(tex) tex -# define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) -# define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) -/* clang-format off */ -# define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) -/* clang-format on */ -# define SMAASample(tex, coord) tex.Sample(LinearSampler, coord) -# define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord) -# define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset) -# define SMAA_FLATTEN [flatten] -# define SMAA_BRANCH [branch] -# define SMAATexture2DMS2(tex) Texture2DMS tex -# define SMAALoad(tex, pos, sample) tex.Load(pos, sample) -# if defined(SMAA_HLSL_4_1) -# define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) -# endif -#endif -#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) || defined(GPU_METAL) || defined(GPU_VULKAN) -# define SMAATexture2D(tex) sampler2D tex -# define SMAATexturePass2D(tex) tex -# define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) -# define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0) -# define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) -# define SMAASample(tex, coord) texture(tex, coord) -# define SMAASamplePoint(tex, coord) texture(tex, coord) -# define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset) -# define SMAA_FLATTEN -# define SMAA_BRANCH -# define lerp(a, b, t) mix(a, b, t) -# define saturate(a) clamp(a, 0.0, 1.0) -# if defined(SMAA_GLSL_4) -# define SMAAGather(tex, coord) textureGather(tex, coord) -# endif -# if defined(SMAA_GLSL_4) -# define mad(a, b, c) fma(a, b, c) -# elif defined(GPU_VULKAN) -/* NOTE(Vulkan) mad macro doesn't work, define each override as work-around. */ -vec4 mad(vec4 a, vec4 b, vec4 c) -{ - return fma(a, b, c); -} -vec3 mad(vec3 a, vec3 b, vec3 c) -{ - return fma(a, b, c); -} -vec2 mad(vec2 a, vec2 b, vec2 c) -{ - return fma(a, b, c); -} -float mad(float a, float b, float c) -{ - return fma(a, b, c); -} -# else -# define mad(a, b, c) (a * b + c) -# endif -/* NOTE(Metal): Types already natively declared in MSL. */ -# ifndef GPU_METAL -# define float2 vec2 -# define float3 vec3 -# define float4 vec4 -# define int2 ivec2 -# define int3 ivec3 -# define int4 ivec4 -# define bool2 bvec2 -# define bool3 bvec3 -# define bool4 bvec4 -# endif -#endif - -/* clang-format off */ -#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL) -# error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL -#endif -/* clang-format on */ - -namespace blender::compositor { - -/* ---------------------------------------------------------------------------- - * Misc functions */ - -/** - * Conditional move: - */ -static void SMAAMovc(float2 cond, float2 &variable, float2 value) -{ - /* Use select function (select(genType A, genType B, genBType cond)). */ - variable = math::interpolate(variable, value, cond); -} - -static void SMAAMovc(float4 cond, float4 &variable, float4 value) -{ - /* Use select function (select(genType A, genType B, genBType cond)). */ - variable = math::interpolate(variable, value, cond); -} - -#if SMAA_INCLUDE_VS -/* ---------------------------------------------------------------------------- - * Vertex Shaders */ - -/** - * Edge Detection Vertex Shader - */ -static void SMAAEdgeDetectionVS(float2 texcoord, int2 size, float4 offset[3]) -{ - offset[0] = float4(texcoord.xy(), texcoord.xy()) + - float4(-1.0f, 0.0f, 0.0f, -1.0f) / float4(size, size); - offset[1] = float4(texcoord.xy(), texcoord.xy()) + - float4(1.0f, 0.0f, 0.0f, 1.0f) / float4(size, size); - offset[2] = float4(texcoord.xy(), texcoord.xy()) + - float4(-2.0f, 0.0f, 0.0f, -2.0f) / float4(size, size); -} - -/** - * Blend Weight Calculation Vertex Shader - */ -static void SMAABlendingWeightCalculationVS(float2 texcoord, - int2 size, - float2 &pixcoord, - float4 offset[3]) -{ - pixcoord = texcoord * float2(size); - - /* We will use these offsets for the searches later on (see @PSEUDO_GATHER4): */ - offset[0] = float4(texcoord.xy(), texcoord.xy()) + - float4(-0.25f, -0.125f, 1.25f, -0.125f) / float4(size, size); - offset[1] = float4(texcoord.xy(), texcoord.xy()) + - float4(-0.125f, -0.25f, -0.125f, 1.25f) / float4(size, size); - - /* And these for the searches, they indicate the ends of the loops: */ - offset[2] = float4(offset[0].x, offset[0].z, offset[1].y, offset[1].w) + - (float4(-2.0f, 2.0f, -2.0f, 2.0f) * float(SMAA_MAX_SEARCH_STEPS)) / - float4(float2(size.x), float2(size.y)); -} - -/** - * Neighborhood Blending Vertex Shader - */ -static void SMAANeighborhoodBlendingVS(float2 texcoord, int2 size, float4 &offset) -{ - offset = float4(texcoord, texcoord) + float4(1.0f, 0.0f, 0.0f, 1.0f) / float4(size, size); -} -#endif /* SMAA_INCLUDE_VS */ - -/** - * Luma Edge Detection - * - * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and - * thus 'colorTex' should be a non-sRGB texture. - */ -static float2 SMAALumaEdgeDetectionPS(float2 texcoord, - float4 offset[3], - SMAATexture2D(colorTex), -#if SMAA_PREDICATION - SMAATexture2D(predicationTex), -#endif - float edge_threshold, - float3 luminance_coefficients, - float local_contrast_adaptation_factor) -{ -#if SMAA_PREDICATION - float2 threshold = SMAACalculatePredicatedThreshold( - texcoord, offset, SMAATexturePass2D(predicationTex)); -#else - /* Calculate the threshold: */ - float2 threshold = float2(edge_threshold, edge_threshold); -#endif - - /* Calculate lumas: */ - // float4 weights = float4(0.2126, 0.7152, 0.0722, 0.0); - float4 weights = float4(luminance_coefficients, 0.0f); - float L = math::dot(SMAASamplePoint(colorTex, texcoord), weights); - - float Lleft = math::dot(SMAASamplePoint(colorTex, offset[0].xy()), weights); - float Ltop = math::dot(SMAASamplePoint(colorTex, offset[0].zw()), weights); - - /* We do the usual threshold: */ - float4 delta; - float2 delta_left_top = math::abs(L - float2(Lleft, Ltop)); - delta.x = delta_left_top.x; - delta.y = delta_left_top.y; - float2 edges = math::step(threshold, delta.xy()); - - /* Then return early if there is no edge: */ - if (math::dot(edges, float2(1.0f, 1.0f)) == 0.0f) { - return float2(0.0f); - } - - /* Calculate right and bottom deltas: */ - float Lright = math::dot(SMAASamplePoint(colorTex, offset[1].xy()), weights); - float Lbottom = math::dot(SMAASamplePoint(colorTex, offset[1].zw()), weights); - float2 delta_right_bottom = math::abs(L - float2(Lright, Lbottom)); - delta.z = delta_right_bottom.x; - delta.w = delta_right_bottom.y; - - /* Calculate the maximum delta in the direct neighborhood: */ - float2 maxDelta = math::max(delta.xy(), delta.zw()); - - /* Calculate left-left and top-top deltas: */ - float Lleftleft = math::dot(SMAASamplePoint(colorTex, offset[2].xy()), weights); - float Ltoptop = math::dot(SMAASamplePoint(colorTex, offset[2].zw()), weights); - float2 delta_left_left_top_top = math::abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); - delta.z = delta_left_left_top_top.x; - delta.w = delta_left_left_top_top.y; - - /* Calculate the final maximum delta: */ - maxDelta = math::max(maxDelta.xy(), delta.zw()); - float finalDelta = math::max(maxDelta.x, maxDelta.y); - - /* Local contrast adaptation: */ - edges *= math::step(finalDelta, local_contrast_adaptation_factor * delta.xy()); - - return edges; -} - -/* ---------------------------------------------------------------------------- - * Diagonal Search Functions */ - -#if !defined(SMAA_DISABLE_DIAG_DETECTION) - -/** - * Allows to decode two binary values from a bilinear-filtered access. - */ -static float2 SMAADecodeDiagBilinearAccess(float2 e) -{ - /* Bilinear access for fetching 'e' have a 0.25 offset, and we are - * interested in the R and G edges: - * - * +---G---+-------+ - * | x o R x | - * +-------+-------+ - * - * Then, if one of these edge is enabled: - * Red: `(0.75 * X + 0.25 * 1) => 0.25 or 1.0` - * Green: `(0.75 * 1 + 0.25 * X) => 0.75 or 1.0` - * - * This function will unpack the values `(mad + mul + round)`: - * wolframalpha.com: `round(x * abs(5 * x - 5 * 0.75))` plot 0 to 1 - */ - e.x = e.x * math::abs(5.0f * e.x - 5.0f * 0.75f); - return math::round(e); -} - -static float4 SMAADecodeDiagBilinearAccess(float4 e) -{ - e.x = e.x * math::abs(5.0f * e.x - 5.0f * 0.75f); - e.z = e.z * math::abs(5.0f * e.z - 5.0f * 0.75f); - return math::round(e); -} - -/** - * These functions allows to perform diagonal pattern searches. - */ -static float2 SMAASearchDiag1( - SMAATexture2D(edgesTex), float2 texcoord, float2 dir, int2 size, float2 &e) -{ - float4 coord = float4(texcoord, -1.0f, 1.0f); - float3 t = float3(1.0f / float2(size), 1.0f); - while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && coord.w > 0.9f) { - float3 increment = mad(t, float3(dir, 1.0f), coord.xyz()); - coord.x = increment.x; - coord.y = increment.y; - coord.z = increment.z; - e = SMAASamplePoint(edgesTex, coord.xy()).xy(); - coord.w = math::dot(e, float2(0.5f, 0.5f)); - } - return coord.zw(); -} - -static float2 SMAASearchDiag2( - SMAATexture2D(edgesTex), float2 texcoord, float2 dir, int2 size, float2 &e) -{ - float4 coord = float4(texcoord, -1.0f, 1.0f); - coord.x += 0.25f / size.x; /* See @SearchDiag2Optimization */ - float3 t = float3(1.0f / float2(size), 1.0f); - while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && coord.w > 0.9f) { - float3 increment = mad(t, float3(dir, 1.0f), coord.xyz()); - coord.x = increment.x; - coord.y = increment.y; - coord.z = increment.z; - - /* @SearchDiag2Optimization */ - /* Fetch both edges at once using bilinear filtering: */ - e = SMAASampleLevelZero(edgesTex, coord.xy()).xy(); - e = SMAADecodeDiagBilinearAccess(e); - - /* Non-optimized version: */ - // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; - // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0), size).r; - - coord.w = math::dot(e, float2(0.5f, 0.5f)); - } - return coord.zw(); -} - -/** - * Similar to SMAAArea, this calculates the area corresponding to a certain - * diagonal distance and crossing edges 'e'. - */ -static float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) -{ - float2 texcoord = mad( - float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); - - /* We do a scale and bias for mapping to texel space: */ - texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5f * SMAA_AREATEX_PIXEL_SIZE); - - /* Diagonal areas are on the second half of the texture: */ - texcoord.x += 0.5f; - - /* Move to proper place, according to the sub-pixel offset: */ - texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; - - /* Do it! */ - return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); -} - -/** - * This searches for diagonal patterns and returns the corresponding weights. - */ -static float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), - SMAATexture2D(areaTex), - float2 texcoord, - float2 e, - float4 subsampleIndices, - int2 size) -{ - float2 weights = float2(0.0f, 0.0f); - - /* Search for the line ends: */ - float4 d; - float2 end; - if (e.x > 0.0f) { - float2 negative_diagonal = SMAASearchDiag1( - SMAATexturePass2D(edgesTex), texcoord, float2(-1.0f, 1.0f), size, end); - d.x = negative_diagonal.x; - d.z = negative_diagonal.y; - d.x += float(end.y > 0.9f); - } - else { - d.x = 0.0f; - d.z = 0.0f; - } - float2 positive_diagonal = SMAASearchDiag1( - SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), size, end); - d.y = positive_diagonal.x; - d.w = positive_diagonal.y; - - SMAA_BRANCH - if (d.x + d.y > 2.0f) { /* `d.x + d.y + 1 > 3`. */ - /* Fetch the crossing edges: */ - float4 coords = float4(texcoord, texcoord) + - float4(-d.x + 0.25f, d.x, d.y, -d.y - 0.25f) / float4(size, size); - float4 c; - float2 left_edge = SMAASampleLevelZeroOffset(edgesTex, coords.xy(), int2(-1, 0), size).xy(); - float2 right_edge = SMAASampleLevelZeroOffset(edgesTex, coords.zw(), int2(1, 0), size).xy(); - c.x = left_edge.x; - c.y = left_edge.y; - c.z = right_edge.x; - c.w = right_edge.y; - float4 decoded_access = SMAADecodeDiagBilinearAccess(c); - c.y = decoded_access.x; - c.x = decoded_access.y; - c.w = decoded_access.z; - c.z = decoded_access.w; - - /* Non-optimized version: */ - // float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); - // float4 c; - // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0), size).g; - // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0), size).r; - // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0), size).g; - // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1), size).r; - - /* Merge crossing edges at each side into a single value: */ - float2 cc = mad(float2(2.0f, 2.0f), float2(c.x, c.z), float2(c.y, c.w)); - - /* Remove the crossing edge if we didn't found the end of the line: */ - SMAAMovc(math::step(0.9f, d.zw()), cc, float2(0.0f, 0.0f)); - - /* Fetch the areas for this line: */ - weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy(), cc, subsampleIndices.z); - } - - /* Search for the line ends: */ - float2 negative_diagonal = SMAASearchDiag2( - SMAATexturePass2D(edgesTex), texcoord, float2(-1.0f, -1.0f), size, end); - d.x = negative_diagonal.x; - d.z = negative_diagonal.y; - if (SMAASamplePointOffset(edgesTex, texcoord, int2(1, 0), size).x > 0.0f) { - float2 positive_diagonal = SMAASearchDiag2( - SMAATexturePass2D(edgesTex), texcoord, float2(1.0f, 1.0f), size, end); - d.y = positive_diagonal.x; - d.w = positive_diagonal.y; - d.y += float(end.y > 0.9f); - } - else { - d.y = 0.0f; - d.w = 0.0f; - } - - SMAA_BRANCH - if (d.x + d.y > 2.0f) { /* `d.x + d.y + 1 > 3` */ - /* Fetch the crossing edges: */ - float4 coords = float4(texcoord, texcoord) + float4(-d.x, -d.x, d.y, d.y) / float4(size, size); - float4 c; - c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy(), int2(-1, 0), size).y; - c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy(), int2(0, -1), size).x; - float2 left_edge = SMAASampleLevelZeroOffset(edgesTex, coords.zw(), int2(1, 0), size).xy(); - c.z = left_edge.y; - c.w = left_edge.x; - float2 cc = mad(float2(2.0f, 2.0f), float2(c.x, c.z), float2(c.y, c.w)); - - /* Remove the crossing edge if we didn't found the end of the line: */ - SMAAMovc(math::step(0.9f, d.zw()), cc, float2(0.0f, 0.0f)); - - /* Fetch the areas for this line: */ - float2 area = SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy(), cc, subsampleIndices.w).xy(); - weights.x += area.y; - weights.y += area.x; - } - - return weights; -} -#endif - -/* ---------------------------------------------------------------------------- - * Horizontal/Vertical Search Functions */ - -/** - * This allows to determine how much length should we add in the last step - * of the searches. It takes the bilinearly interpolated edge (see - * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and - * crossing edges are active. - */ -static float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) -{ - /* The texture is flipped vertically, with left and right cases taking half - * of the space horizontally: */ - float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5f, -1.0f); - float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0f); - - /* Scale and bias to access texel centers: */ - scale += float2(-1.0f, 1.0f); - bias += float2(0.5f, -0.5f); - - /* Convert from pixel coordinates to texcoords: - * (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped). */ - scale *= 1.0f / SMAA_SEARCHTEX_PACKED_SIZE; - bias *= 1.0f / SMAA_SEARCHTEX_PACKED_SIZE; - - /* Lookup the search texture: */ - return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, mad(scale, e, bias))); -} - -/** - * Horizontal/vertical search functions for the 2nd pass. - */ -static float SMAASearchXLeft( - SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end, int2 size) -{ - /** - * @PSEUDO_GATHER4 - * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to - * sample between edge, thus fetching four edges in a row. - * Sampling with different offsets in each direction allows to disambiguate - * which edges are active from the four fetched ones. - */ - float2 e = float2(0.0f, 1.0f); - while (texcoord.x > end && e.y > 0.8281f && /* Is there some edge not activated? */ - e.x == 0.0f) /* Or is there a crossing edge that breaks the line? */ - { - e = SMAASampleLevelZero(edgesTex, texcoord).xy(); - texcoord = texcoord - float2(2.0f, 0.0f) / float2(size); - } - - float offset = mad( - -(255.0f / 127.0f), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0f), 3.25f); - return texcoord.x + offset / size.x; - - /* Non-optimized version: - * We correct the previous (-0.25, -0.125) offset we applied: */ - // texcoord.x += 0.25 * SMAA_RT_METRICS.x; - - /* The searches are bias by 1, so adjust the coords accordingly: */ - // texcoord.x += SMAA_RT_METRICS.x; - - /* Disambiguate the length added by the last step: */ - // texcoord.x += 2.0 * SMAA_RT_METRICS.x; /* Undo last step. */ - // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * - // SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); - // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); -} - -static float SMAASearchXRight( - SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end, int2 size) -{ - float2 e = float2(0.0f, 1.0f); - while (texcoord.x < end && e.y > 0.8281f && /* Is there some edge not activated? */ - e.x == 0.0f) /* Or is there a crossing edge that breaks the line? */ - { - e = SMAASampleLevelZero(edgesTex, texcoord).xy(); - texcoord = texcoord + float2(2.0f, 0.0f) / float2(size); - } - float offset = mad( - -(255.0f / 127.0f), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5f), 3.25f); - return texcoord.x - offset / size.x; -} - -static float SMAASearchYUp( - SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end, int2 size) -{ - float2 e = float2(1.0f, 0.0f); - while (texcoord.y > end && e.x > 0.8281f && /* Is there some edge not activated? */ - e.y == 0.0f) /* Or is there a crossing edge that breaks the line? */ - { - e = SMAASampleLevelZero(edgesTex, texcoord).xy(); - texcoord = texcoord - float2(0.0f, 2.0f) / float2(size); - } - float2 flipped_edge = float2(e.y, e.x); - float offset = mad(-(255.0f / 127.0f), - SMAASearchLength(SMAATexturePass2D(searchTex), flipped_edge, 0.0f), - 3.25f); - return texcoord.y + offset / size.y; -} - -static float SMAASearchYDown( - SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end, int2 size) -{ - float2 e = float2(1.0f, 0.0f); - while (texcoord.y < end && e.x > 0.8281f && /* Is there some edge not activated? */ - e.y == 0.0f) /* Or is there a crossing edge that breaks the line? */ - { - e = SMAASampleLevelZero(edgesTex, texcoord).xy(); - texcoord = texcoord + float2(0.0f, 2.0f) / float2(size); - } - float2 flipped_edge = float2(e.y, e.x); - float offset = mad(-(255.0f / 127.0f), - SMAASearchLength(SMAATexturePass2D(searchTex), flipped_edge, 0.5f), - 3.25f); - return texcoord.y - offset / size.y; -} - -/** - * Ok, we have the distance and both crossing edges. So, what are the areas - * at each side of current edge? - */ -static float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) -{ - /* Rounding prevents precision errors of bilinear filtering: */ - float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), - math::round(4.0f * float2(e1, e2)), - dist); - - /* We do a scale and bias for mapping to texel space: */ - texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5f * SMAA_AREATEX_PIXEL_SIZE); - - /* Move to proper place, according to the sub-pixel offset: */ - texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); - - /* Do it! */ - return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); -} - -/* ---------------------------------------------------------------------------- - * Corner Detection Functions */ - -static void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), - float2 &weights, - float4 texcoord, - float2 d, - int2 size, - int corner_rounding) -{ -#if !defined(SMAA_DISABLE_CORNER_DETECTION) - float2 leftRight = math::step(d, float2(d.y, d.x)); - float2 rounding = (1.0f - corner_rounding / 100.0f) * leftRight; - - rounding /= leftRight.x + leftRight.y; /* Reduce blending for pixels in the center of a line. */ - - float2 factor = float2(1.0f, 1.0f); - factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy(), int2(0, 1), size).x; - factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw(), int2(1, 1), size).x; - factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy(), int2(0, -2), size).x; - factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw(), int2(1, -2), size).x; - - weights *= saturate(factor); -#endif -} - -static void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), - float2 &weights, - float4 texcoord, - float2 d, - int2 size, - int corner_rounding) -{ -#if !defined(SMAA_DISABLE_CORNER_DETECTION) - float2 leftRight = math::step(d, float2(d.y, d.x)); - float2 rounding = (1.0f - corner_rounding / 100.0f) * leftRight; - - rounding /= leftRight.x + leftRight.y; - - float2 factor = float2(1.0f, 1.0f); - factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy(), int2(1, 0), size).y; - factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw(), int2(1, 1), size).y; - factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy(), int2(-2, 0), size).y; - factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw(), int2(-2, 1), size).y; - - weights *= saturate(factor); -#endif -} - -/* ---------------------------------------------------------------------------- - * Blending Weight Calculation Pixel Shader (Second Pass) */ - -static float4 SMAABlendingWeightCalculationPS(float2 texcoord, - float2 pixcoord, - float4 offset[3], - MemoryBuffer *edgesTex, - MemoryBuffer *areaTex, - MemoryBuffer *searchTex, - float4 subsampleIndices, - int2 size, - int corner_rounding) -{ - /* Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. */ - float4 weights = float4(0.0f, 0.0f, 0.0f, 0.0f); - - float2 e = SMAASamplePoint(edgesTex, texcoord).xy(); - - SMAA_BRANCH - if (e.y > 0.0f) { /* Edge at north. */ -#if !defined(SMAA_DISABLE_DIAG_DETECTION) - /* Diagonals have both north and west edges, so searching for them in - * one of the boundaries is enough. */ - float2 diagonal_weights = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), - SMAATexturePass2D(areaTex), - texcoord, - e, - subsampleIndices, - size); - - weights.x = diagonal_weights.x; - weights.y = diagonal_weights.y; - - /* We give priority to diagonals, so if we find a diagonal we skip - * horizontal/vertical processing. */ - SMAA_BRANCH - if (weights.x == -weights.y) { /* `weights.x + weights.y == 0.0` */ -#endif - - float2 d; - - /* Find the distance to the left: */ - float3 coords; - coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), - SMAATexturePass2D(searchTex), - offset[0].xy(), - offset[2].x, - size); - coords.y = - offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) - d.x = coords.x; - - /* Now fetch the left crossing edges, two at a time using bilinear - * filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to - * discern what value each edge has: */ - float e1 = SMAASampleLevelZero(edgesTex, coords.xy()).x; - - /* Find the distance to the right: */ - coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), - SMAATexturePass2D(searchTex), - offset[0].zw(), - offset[2].y, - size); - d.y = coords.z; - - /* We want the distances to be in pixel units (doing this here allows - * better interleaving of arithmetic and memory accesses): */ - d = math::abs(math::round(mad(float2(size.x), d, -float2(pixcoord.x)))); - - /* SMAAArea below needs a sqrt, as the areas texture is compressed quadratically: */ - float2 sqrt_d = math::sqrt(d); - - /* Fetch the right crossing edges: */ - float e2 = - SMAASampleLevelZeroOffset(edgesTex, float2(coords.z, coords.y), int2(1, 0), size).x; - - /* Ok, we know how this pattern looks like, now it is time for getting the actual area: */ - float2 area = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y); - weights.x = area.x; - weights.y = area.y; - - /* Fix corners: */ - coords.y = texcoord.y; - - float2 corner_weight = weights.xy(); - SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), - corner_weight, - float4(coords.xy(), coords.z, coords.y), - d, - size, - corner_rounding); - weights.x = corner_weight.x; - weights.y = corner_weight.y; - -#if !defined(SMAA_DISABLE_DIAG_DETECTION) - } - else - e.x = 0.0f; /* Skip vertical processing. */ -#endif - } - - SMAA_BRANCH - if (e.x > 0.0f) { /* Edge at west. */ - float2 d; - - /* Find the distance to the top: */ - float3 coords; - coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), - SMAATexturePass2D(searchTex), - offset[1].xy(), - offset[2].z, - size); - coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x; - d.x = coords.y; - - /* Fetch the top crossing edges: */ - float e1 = SMAASampleLevelZero(edgesTex, coords.xy()).y; - - /* Find the distance to the bottom: */ - coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), - SMAATexturePass2D(searchTex), - offset[1].zw(), - offset[2].w, - size); - d.y = coords.z; - - /* We want the distances to be in pixel units: */ - d = math::abs(math::round(mad(float2(size.y), d, -float2(pixcoord.y)))); - - /* SMAAArea below needs a sqrt, as the areas texture is compressed quadratically: */ - float2 sqrt_d = math::sqrt(d); - - /* Fetch the bottom crossing edges: */ - float e2 = SMAASampleLevelZeroOffset(edgesTex, float2(coords.x, coords.z), int2(0, 1), size).y; - - /* Get the area for this direction: */ - float2 area = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x); - weights.z = area.x; - weights.w = area.y; - - /* Fix corners: */ - coords.x = texcoord.x; - - float2 corner_weight = weights.zw(); - SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), - corner_weight, - float4(coords.xy(), coords.x, coords.z), - d, - size, - corner_rounding); - weights.z = corner_weight.x; - weights.w = corner_weight.y; - } - - return weights; -} - -/* ---------------------------------------------------------------------------- - * Neighborhood Blending Pixel Shader (Third Pass) */ - -static float4 SMAANeighborhoodBlendingPS(float2 texcoord, - float4 offset, - SMAATexture2D(colorTex), - SMAATexture2D(blendTex), -#if SMAA_REPROJECTION - SMAATexture2D(velocityTex), -#endif - int2 size) -{ - /* Fetch the blending weights for current pixel: */ - float4 a; - a.x = SMAASample(blendTex, offset.xy()).w; // Right - a.y = SMAASample(blendTex, offset.zw()).y; // Top - a.z = SMAASample(blendTex, texcoord).z; // Left - a.w = SMAASample(blendTex, texcoord).x; // Bottom - - /* Is there any blending weight with a value greater than 0.0? */ - SMAA_BRANCH - if (math::dot(a, float4(1.0f, 1.0f, 1.0f, 1.0f)) < 1e-5f) { - float4 color = SMAASampleLevelZero(colorTex, texcoord); - -#if SMAA_REPROJECTION - float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord)); - - /* Pack velocity into the alpha channel: */ - color.a = math::sqrt(5.0f * math::length(velocity)); -#endif - - return color; - } - else { - bool h = math::max(a.x, a.z) > math::max(a.y, a.w); /* `max(horizontal) > max(vertical)`. */ - - /* Calculate the blending offsets: */ - float4 blendingOffset = float4(0.0f, a.y, 0.0f, a.w); - float2 blendingWeight = float2(a.y, a.w); - SMAAMovc(float4(h), blendingOffset, float4(a.x, 0.0f, a.z, 0.0f)); - SMAAMovc(float2(h), blendingWeight, float2(a.x, a.z)); - blendingWeight /= math::dot(blendingWeight, float2(1.0f, 1.0f)); - - /* Calculate the texture coordinates: */ - float4 blendingCoord = float4(texcoord, texcoord) + blendingOffset / float4(size, -size); - - /* We exploit bilinear filtering to mix current pixel with the chosen neighbor: */ - float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy()); - color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw()); - -#if SMAA_REPROJECTION - /* Anti-alias velocity for proper reprojection in a later stage: */ - float2 velocity = blendingWeight.x * - SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy())); - velocity += blendingWeight.y * - SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw())); - - /* Pack velocity into the alpha channel: */ - color.a = math::sqrt(5.0f * math::length(velocity)); -#endif - - return color; - } -} - -SMAAOperation::SMAAOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; -} - -void SMAAOperation::get_area_of_interest(const int /*input_idx*/, - const rcti &output_area, - rcti &r_input_area) -{ - r_input_area.xmax = output_area.xmax + - math::max(SMAA_MAX_SEARCH_STEPS, SMAA_MAX_SEARCH_STEPS_DIAG + 1); - r_input_area.xmin = output_area.xmin - math::max(math::max(SMAA_MAX_SEARCH_STEPS - 1, 1), - SMAA_MAX_SEARCH_STEPS_DIAG + 1); - r_input_area.ymax = output_area.ymax + - math::max(SMAA_MAX_SEARCH_STEPS, SMAA_MAX_SEARCH_STEPS_DIAG); - r_input_area.ymin = output_area.ymin - math::max(math::max(SMAA_MAX_SEARCH_STEPS - 1, 1), - SMAA_MAX_SEARCH_STEPS_DIAG); -} - -void SMAAOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - const MemoryBuffer *image = inputs[0]; - if (image->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), image->get_elem(0, 0)); - return; - } - - const int2 size = int2(image->get_width(), image->get_height()); - MemoryBuffer edges(DataType::Float2, size.x, size.y); - - float3 luminance_coefficients; - IMB_colormanagement_get_luminance_coefficients(luminance_coefficients); - - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - float2 coordinates = (float2(texel) + float2(0.5f)) / float2(size); - - float4 offset[3]; - SMAAEdgeDetectionVS(coordinates, size, offset); - - float2 edge = SMAALumaEdgeDetectionPS(coordinates, - offset, - image, - threshold_, - luminance_coefficients, - local_contrast_adaptation_factor_); - copy_v2_v2(edges.get_elem(texel.x, texel.y), edge); - } - } - }); - - MemoryBuffer blending_weights(DataType::Color, size.x, size.y); - - MemoryBuffer area_texture(DataType::Float2, AREATEX_WIDTH, AREATEX_HEIGHT); - area_texture.copy_from(areaTexBytes, area_texture.get_rect()); - - MemoryBuffer search_texture(DataType::Value, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT); - search_texture.copy_from(searchTexBytes, search_texture.get_rect()); - - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - float2 coordinates = (float2(texel) + float2(0.5f)) / float2(size); - - float4 offset[3]; - float2 pixel_coordinates; - SMAABlendingWeightCalculationVS(coordinates, size, pixel_coordinates, offset); - - float4 weights = SMAABlendingWeightCalculationPS(coordinates, - pixel_coordinates, - offset, - &edges, - &area_texture, - &search_texture, - float4(0.0f), - size, - corner_rounding_); - copy_v4_v4(blending_weights.get_elem(texel.x, texel.y), weights); - } - } - }); - - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - int2 texel = int2(x, y); - float2 coordinates = (float2(texel) + float2(0.5f)) / float2(size); - - float4 offset; - SMAANeighborhoodBlendingVS(coordinates, size, offset); - - float4 result = SMAANeighborhoodBlendingPS( - coordinates, offset, image, &blending_weights, size); - copy_v4_v4(output->get_elem(texel.x, texel.y), result); - } - } - }); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SMAAOperation.h b/source/blender/compositor/operations/COM_SMAAOperation.h deleted file mode 100644 index 3f379e30716..00000000000 --- a/source/blender/compositor/operations/COM_SMAAOperation.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-FileCopyrightText: 2017 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -class SMAAOperation : public NodeOperation { - protected: - float threshold_ = 0.1f; - float local_contrast_adaptation_factor_ = 2.0f; - int corner_rounding_ = 25; - - public: - SMAAOperation(); - - void set_threshold(float threshold) - { - threshold_ = threshold; - } - - void set_local_contrast_adaptation_factor(float factor) - { - local_contrast_adaptation_factor_ = factor; - } - - void set_corner_rounding(int corner_rounding) - { - corner_rounding_ = corner_rounding; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc deleted file mode 100644 index 8003b143d6d..00000000000 --- a/source/blender/compositor/operations/COM_ScaleOperation.cc +++ /dev/null @@ -1,343 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ScaleOperation.h" -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -#define USE_FORCE_BILINEAR -/* XXX(@ideasman42): ignore input and use default from old compositor, - * could become an option like the transform node. - * - * NOTE: use bilinear because bicubic makes fuzzy even when not scaling at all (1:1) - */ - -BaseScaleOperation::BaseScaleOperation() -{ -#ifdef USE_FORCE_BILINEAR - sampler_ = int(PixelSampler::Bilinear); -#else - sampler_ = -1; -#endif - variable_size_ = false; -} - -ScaleOperation::ScaleOperation() : ScaleOperation(DataType::Color) {} - -ScaleOperation::ScaleOperation(DataType data_type) : BaseScaleOperation() -{ - this->add_input_socket(data_type, ResizeMode::None); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(data_type); - flags_.can_be_constant = true; -} - -float ScaleOperation::get_constant_scale(const int input_op_idx, const float factor) -{ - const bool is_constant = get_input_operation(input_op_idx)->get_flags().is_constant_operation; - if (is_constant) { - return ((ConstantOperation *)get_input_operation(input_op_idx))->get_constant_elem()[0] * - factor; - } - - return 1.0f; -} - -float ScaleOperation::get_constant_scale_x(const float width) -{ - return get_constant_scale(X_INPUT_INDEX, get_relative_scale_x_factor(width)); -} - -float ScaleOperation::get_constant_scale_y(const float height) -{ - return get_constant_scale(Y_INPUT_INDEX, get_relative_scale_y_factor(height)); -} - -bool ScaleOperation::is_scaling_variable() -{ - return !get_input_operation(X_INPUT_INDEX)->get_flags().is_constant_operation || - !get_input_operation(Y_INPUT_INDEX)->get_flags().is_constant_operation; -} - -void ScaleOperation::scale_area(rcti &area, float relative_scale_x, float relative_scale_y) -{ - const rcti src_area = area; - const float center_x = BLI_rcti_size_x(&area) / 2.0f; - const float center_y = BLI_rcti_size_y(&area) / 2.0f; - area.xmin = floorf(scale_coord(area.xmin, center_x, relative_scale_x)); - area.xmax = ceilf(scale_coord(area.xmax, center_x, relative_scale_x)); - area.ymin = floorf(scale_coord(area.ymin, center_y, relative_scale_y)); - area.ymax = ceilf(scale_coord(area.ymax, center_y, relative_scale_y)); - - float scale_offset_x, scale_offset_y; - ScaleOperation::get_scale_offset(src_area, area, scale_offset_x, scale_offset_y); - BLI_rcti_translate(&area, -scale_offset_x, -scale_offset_y); -} - -void ScaleOperation::clamp_area_size_max(rcti &area, Size2f max_size) -{ - - if (BLI_rcti_size_x(&area) > max_size.x) { - area.xmax = area.xmin + max_size.x; - } - if (BLI_rcti_size_y(&area) > max_size.y) { - area.ymax = area.ymin + max_size.y; - } -} - -void ScaleOperation::init_data() -{ - canvas_center_x_ = canvas_.xmin + get_width() / 2.0f; - canvas_center_y_ = canvas_.ymin + get_height() / 2.0f; -} - -void ScaleOperation::get_scale_offset(const rcti &input_canvas, - const rcti &scale_canvas, - float &r_scale_offset_x, - float &r_scale_offset_y) -{ - r_scale_offset_x = (BLI_rcti_size_x(&input_canvas) - BLI_rcti_size_x(&scale_canvas)) / 2.0f; - r_scale_offset_y = (BLI_rcti_size_y(&input_canvas) - BLI_rcti_size_y(&scale_canvas)) / 2.0f; -} - -void ScaleOperation::get_scale_area_of_interest(const rcti &input_canvas, - const rcti &scale_canvas, - const float relative_scale_x, - const float relative_scale_y, - const rcti &output_area, - rcti &r_input_area) -{ - const float scale_center_x = BLI_rcti_size_x(&input_canvas) / 2.0f; - const float scale_center_y = BLI_rcti_size_y(&input_canvas) / 2.0f; - float scale_offset_x, scale_offset_y; - ScaleOperation::get_scale_offset(input_canvas, scale_canvas, scale_offset_x, scale_offset_y); - - r_input_area.xmin = floorf( - scale_coord_inverted(output_area.xmin + scale_offset_x, scale_center_x, relative_scale_x)); - r_input_area.xmax = ceilf( - scale_coord_inverted(output_area.xmax + scale_offset_x, scale_center_x, relative_scale_x)); - r_input_area.ymin = floorf( - scale_coord_inverted(output_area.ymin + scale_offset_y, scale_center_y, relative_scale_y)); - r_input_area.ymax = ceilf( - scale_coord_inverted(output_area.ymax + scale_offset_y, scale_center_y, relative_scale_y)); -} - -void ScaleOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - r_input_area = output_area; - if (input_idx != 0 || is_scaling_variable()) { - return; - } - - NodeOperation *image_op = get_input_operation(IMAGE_INPUT_INDEX); - const float scale_x = get_constant_scale_x(image_op->get_width()); - const float scale_y = get_constant_scale_y(image_op->get_height()); - - get_scale_area_of_interest( - image_op->get_canvas(), this->get_canvas(), scale_x, scale_y, output_area, r_input_area); - expand_area_for_sampler(r_input_area, (PixelSampler)sampler_); -} - -void ScaleOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - NodeOperation *input_image_op = get_input_operation(IMAGE_INPUT_INDEX); - const int input_image_width = input_image_op->get_width(); - const int input_image_height = input_image_op->get_height(); - const float scale_x_factor = get_relative_scale_x_factor(input_image_width); - const float scale_y_factor = get_relative_scale_y_factor(input_image_height); - const float scale_center_x = input_image_width / 2.0f; - const float scale_center_y = input_image_height / 2.0f; - float from_scale_offset_x, from_scale_offset_y; - ScaleOperation::get_scale_offset( - input_image_op->get_canvas(), this->get_canvas(), from_scale_offset_x, from_scale_offset_y); - - const MemoryBuffer *input_image = inputs[IMAGE_INPUT_INDEX]; - MemoryBuffer *input_x = inputs[X_INPUT_INDEX]; - MemoryBuffer *input_y = inputs[Y_INPUT_INDEX]; - BuffersIterator it = output->iterate_with({input_x, input_y}, area); - for (; !it.is_end(); ++it) { - const float rel_scale_x = *it.in(0) * scale_x_factor; - const float rel_scale_y = *it.in(1) * scale_y_factor; - const float scaled_x = scale_coord_inverted(from_scale_offset_x + canvas_.xmin + 0.5f + it.x, - scale_center_x, - rel_scale_x) - - 0.5f; - const float scaled_y = scale_coord_inverted(from_scale_offset_y + canvas_.ymin + 0.5f + it.y, - scale_center_y, - rel_scale_y) - - 0.5f; - - input_image->read_elem_sampled( - scaled_x - canvas_.xmin, scaled_y - canvas_.ymin, (PixelSampler)sampler_, it.out); - } -} - -void ScaleOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - const bool image_determined = - get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area); - if (image_determined) { - rcti image_canvas = r_area; - rcti unused = COM_AREA_NONE; - NodeOperationInput *x_socket = get_input_socket(X_INPUT_INDEX); - NodeOperationInput *y_socket = get_input_socket(Y_INPUT_INDEX); - x_socket->determine_canvas(image_canvas, unused); - y_socket->determine_canvas(image_canvas, unused); - if (is_scaling_variable()) { - /* Do not scale canvas. */ - return; - } - - /* Determine scaled canvas. */ - const float input_width = BLI_rcti_size_x(&r_area); - const float input_height = BLI_rcti_size_y(&r_area); - const float scale_x = get_constant_scale_x(input_width); - const float scale_y = get_constant_scale_y(input_height); - scale_area(r_area, scale_x, scale_y); - - /* Re-determine canvases of x and y constant inputs with scaled canvas as preferred. */ - get_input_operation(X_INPUT_INDEX)->unset_canvas(); - get_input_operation(Y_INPUT_INDEX)->unset_canvas(); - x_socket->determine_canvas(r_area, unused); - y_socket->determine_canvas(r_area, unused); - } -} - -ScaleRelativeOperation::ScaleRelativeOperation() : ScaleOperation() {} - -ScaleRelativeOperation::ScaleRelativeOperation(DataType data_type) : ScaleOperation(data_type) {} - -ScaleFixedSizeOperation::ScaleFixedSizeOperation() : BaseScaleOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::None); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); - is_offset_ = false; -} - -void ScaleFixedSizeOperation::init_data(const rcti &input_canvas) -{ - const int input_width = BLI_rcti_size_x(&input_canvas); - const int input_height = BLI_rcti_size_y(&input_canvas); - rel_x_ = input_width / float(new_width_); - rel_y_ = input_height / float(new_height_); - - /* *** all the options below are for a fairly special case - camera framing *** */ - if (offset_x_ != 0.0f || offset_y_ != 0.0f) { - is_offset_ = true; - - if (new_width_ > new_height_) { - offset_x_ *= new_width_; - offset_y_ *= new_width_; - } - else { - offset_x_ *= new_height_; - offset_y_ *= new_height_; - } - } - - if (is_aspect_) { - /* apply aspect from clip */ - const float w_src = input_width; - const float h_src = input_height; - - /* destination aspect is already applied from the camera frame */ - const float w_dst = new_width_; - const float h_dst = new_height_; - - const float asp_src = w_src / h_src; - const float asp_dst = w_dst / h_dst; - - if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { - if ((asp_src > asp_dst) == (is_crop_ == true)) { - /* fit X */ - const float div = asp_src / asp_dst; - rel_x_ /= div; - offset_x_ += ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f; - if (is_crop_) { - int fit_width = new_width_ * div; - - const int added_width = fit_width - new_width_; - new_width_ += added_width; - offset_x_ += added_width / 2.0f; - } - } - else { - /* fit Y */ - const float div = asp_dst / asp_src; - rel_y_ /= div; - offset_y_ += ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; - if (is_crop_) { - int fit_height = new_height_ * div; - - const int added_height = fit_height - new_height_; - new_height_ += added_height; - offset_y_ += added_height / 2.0f; - } - } - - is_offset_ = true; - } - } - /* *** end framing options *** */ -} - -void ScaleFixedSizeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - rcti local_preferred = preferred_area; - local_preferred.xmax = local_preferred.xmin + new_width_; - local_preferred.ymax = local_preferred.ymin + new_height_; - rcti input_canvas = COM_AREA_NONE; - const bool input_determined = get_input_socket(0)->determine_canvas(local_preferred, - input_canvas); - if (input_determined) { - init_data(input_canvas); - r_area = input_canvas; - r_area.xmin /= rel_x_; - r_area.ymin /= rel_y_; - r_area.xmin += offset_x_; - r_area.ymin += offset_y_; - - r_area.xmax = r_area.xmin + new_width_; - r_area.ymax = r_area.ymin + new_height_; - } -} - -void ScaleFixedSizeOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - UNUSED_VARS_NDEBUG(input_idx); - - r_input_area.xmax = ceilf((output_area.xmax - offset_x_) * rel_x_); - r_input_area.xmin = floorf((output_area.xmin - offset_x_) * rel_x_); - r_input_area.ymax = ceilf((output_area.ymax - offset_y_) * rel_y_); - r_input_area.ymin = floorf((output_area.ymin - offset_y_) * rel_y_); - expand_area_for_sampler(r_input_area, (PixelSampler)sampler_); -} - -void ScaleFixedSizeOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[0]; - PixelSampler sampler = (PixelSampler)sampler_; - BuffersIterator it = output->iterate_with({}, area); - const float add_x = (canvas_.xmin + 0.5f - offset_x_) * rel_x_ - canvas_.xmin - 0.5f; - const float add_y = (canvas_.ymin + 0.5f - offset_y_) * rel_y_ - canvas_.ymin - 0.5f; - for (; !it.is_end(); ++it) { - const float nx = it.x * rel_x_ + add_x; - const float ny = it.y * rel_y_ + add_y; - input_img->read_elem_sampled(nx, ny, sampler, it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h deleted file mode 100644 index 254a24b4284..00000000000 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class BaseScaleOperation : public MultiThreadedOperation { - - public: - void set_sampler(PixelSampler sampler) - { - sampler_ = (int)sampler; - } - void set_variable_size(bool variable_size) - { - variable_size_ = variable_size; - }; - - protected: - BaseScaleOperation(); - - PixelSampler get_effective_sampler(PixelSampler sampler) - { - return (sampler_ == -1) ? sampler : (PixelSampler)sampler_; - } - - int sampler_; - bool variable_size_; -}; - -class ScaleOperation : public BaseScaleOperation { - public: - static constexpr float MIN_RELATIVE_SCALE = 0.0001f; - - protected: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int X_INPUT_INDEX = 1; - static constexpr int Y_INPUT_INDEX = 2; - - float canvas_center_x_; - float canvas_center_y_; - - public: - ScaleOperation(); - ScaleOperation(DataType data_type); - - static float scale_coord(const float coord, const float center, const float relative_scale) - { - return center + (coord - center) * std::max(relative_scale, MIN_RELATIVE_SCALE); - } - - static float scale_coord_inverted(const float coord, - const float center, - const float relative_scale) - { - return center + (coord - center) / std::max(relative_scale, MIN_RELATIVE_SCALE); - } - - static void get_scale_offset(const rcti &input_canvas, - const rcti &scale_canvas, - float &r_scale_offset_x, - float &r_scale_offset_y); - static void scale_area(rcti &area, float relative_scale_x, float relative_scale_y); - static void get_scale_area_of_interest(const rcti &input_canvas, - const rcti &scale_canvas, - float relative_scale_x, - float relative_scale_y, - const rcti &output_area, - rcti &r_input_area); - static void clamp_area_size_max(rcti &area, Size2f max_size); - - void init_data() override; - - 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 inputs) override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - protected: - virtual float get_relative_scale_x_factor(float width) = 0; - virtual float get_relative_scale_y_factor(float height) = 0; - - private: - bool is_scaling_variable(); - float get_constant_scale(int input_op_idx, float factor); - float get_constant_scale_x(float width); - float get_constant_scale_y(float height); -}; - -class ScaleRelativeOperation : public ScaleOperation { - public: - ScaleRelativeOperation(); - ScaleRelativeOperation(DataType data_type); - - float get_relative_scale_x_factor(float /*width*/) override - { - return 1.0f; - } - - float get_relative_scale_y_factor(float /*height*/) override - { - return 1.0f; - } -}; - -class ScaleAbsoluteOperation : public ScaleOperation { - public: - float get_relative_scale_x_factor(float width) override - { - return 1.0f / width; - } - - float get_relative_scale_y_factor(float height) override - { - return 1.0f / height; - } -}; - -class ScaleFixedSizeOperation : public BaseScaleOperation { - int new_width_; - int new_height_; - float rel_x_; - float rel_y_; - - /* center is only used for aspect correction */ - float offset_x_; - float offset_y_; - bool is_aspect_; - bool is_crop_; - /* set from other properties on initialization, - * check if we need to apply offset */ - bool is_offset_; - - public: - /** Absolute fixed size. */ - ScaleFixedSizeOperation(); - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_new_width(int width) - { - new_width_ = width; - } - void set_new_height(int height) - { - new_height_ = height; - } - void set_is_aspect(bool is_aspect) - { - is_aspect_ = is_aspect; - } - void set_is_crop(bool is_crop) - { - is_crop_ = is_crop; - } - void set_offset(float x, float y) - { - offset_x_ = x; - offset_y_ = y; - } - - 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 inputs) override; - - private: - void init_data(const rcti &input_canvas); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc deleted file mode 100644 index 9d9c5f92bae..00000000000 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ScreenLensDistortionOperation.h" - -#include "COM_ConstantOperation.h" - -#include "BLI_rand.h" -#include "BLI_time.h" - -namespace blender::compositor { - -ScreenLensDistortionOperation::ScreenLensDistortionOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; - distortion_ = 0.0f; - dispersion_ = 0.0f; - distortion_const_ = false; - dispersion_const_ = false; - variables_ready_ = false; -} - -void ScreenLensDistortionOperation::set_distortion(float distortion) -{ - distortion_ = distortion; - distortion_const_ = true; -} - -void ScreenLensDistortionOperation::set_dispersion(float dispersion) -{ - dispersion_ = dispersion; - dispersion_const_ = true; -} - -void ScreenLensDistortionOperation::init_data() -{ - cx_ = 0.5f * float(get_width()); - cy_ = 0.5f * float(get_height()); - - NodeOperation *distortion_op = get_input_operation(1); - NodeOperation *dispersion_op = get_input_operation(2); - if (!distortion_const_ && distortion_op->get_flags().is_constant_operation) { - distortion_ = static_cast(distortion_op)->get_constant_elem()[0]; - } - if (!dispersion_const_ && distortion_op->get_flags().is_constant_operation) { - dispersion_ = static_cast(dispersion_op)->get_constant_elem()[0]; - } - update_variables(distortion_, dispersion_); -} - -void ScreenLensDistortionOperation::init_execution() -{ - SocketReader *input_reader = this->get_input_socket_reader(0); - - uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX); - rng_seed ^= uint(POINTER_AS_INT(input_reader)); - rng_ = BLI_rng_new(rng_seed); -} - -void ScreenLensDistortionOperation::get_uv(const float xy[2], float uv[2]) const -{ - uv[0] = sc_ * ((xy[0] + 0.5f) - cx_) / cx_; - uv[1] = sc_ * ((xy[1] + 0.5f) - cy_) / cy_; -} - -void ScreenLensDistortionOperation::distort_uv(const float uv[2], float t, float xy[2]) const -{ - float d = 1.0f / (1.0f + sqrtf(t)); - xy[0] = (uv[0] * d + 0.5f) * get_width() - 0.5f; - xy[1] = (uv[1] * d + 0.5f) * get_height() - 0.5f; -} - -bool ScreenLensDistortionOperation::get_delta(float r_sq, - float k4, - const float uv[2], - float delta[2]) const -{ - float t = 1.0f - k4 * r_sq; - if (t >= 0.0f) { - distort_uv(uv, t, delta); - return true; - } - - return false; -} - -void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer, - int a, - int b, - float r_sq, - const float uv[2], - const float delta[3][2], - float sum[4], - int count[3]) const -{ - float color[4]; - - float dsf = len_v2v2(delta[a], delta[b]) + 1.0f; - int ds = jitter_ ? (dsf < 4.0f ? 2 : int(sqrtf(dsf))) : int(dsf); - float sd = 1.0f / float(ds); - - float k4 = k4_[a]; - float dk4 = dk4_[a]; - - for (float z = 0; z < ds; z++) { - float tz = (z + (jitter_ ? BLI_rng_get_float(rng_) : 0.5f)) * sd; - float t = 1.0f - (k4 + tz * dk4) * r_sq; - - float xy[2]; - distort_uv(uv, t, xy); - buffer->read_elem_bilinear(xy[0], xy[1], color); - - sum[a] += (1.0f - tz) * color[a]; - sum[b] += (tz)*color[b]; - count[a]++; - count[b]++; - } -} - -void ScreenLensDistortionOperation::deinit_execution() -{ - BLI_rng_free(rng_); -} - -void ScreenLensDistortionOperation::determineUV(float result[6], float x, float y) const -{ - const float xy[2] = {x, y}; - float uv[2]; - get_uv(xy, uv); - float uv_dot = len_squared_v2(uv); - - copy_v2_v2(result + 0, xy); - copy_v2_v2(result + 2, xy); - copy_v2_v2(result + 4, xy); - get_delta(uv_dot, k4_[0], uv, result + 0); - get_delta(uv_dot, k4_[1], uv, result + 2); - get_delta(uv_dot, k4_[2], uv, result + 4); -} - -void ScreenLensDistortionOperation::update_variables(float distortion, float dispersion) -{ - k_[1] = max_ff(min_ff(distortion, 1.0f), -0.999f); - /* Smaller dispersion range for somewhat more control. */ - float d = 0.25f * max_ff(min_ff(dispersion, 1.0f), 0.0f); - k_[0] = max_ff(min_ff((k_[1] + d), 1.0f), -0.999f); - k_[2] = max_ff(min_ff((k_[1] - d), 1.0f), -0.999f); - maxk_ = max_fff(k_[0], k_[1], k_[2]); - sc_ = (fit_ && (maxk_ > 0.0f)) ? (1.0f / (1.0f + 2.0f * maxk_)) : (1.0f / (1.0f + maxk_)); - dk4_[0] = 4.0f * (k_[1] - k_[0]); - dk4_[1] = 4.0f * (k_[2] - k_[1]); - dk4_[2] = 0.0f; /* unused */ - - mul_v3_v3fl(k4_, k_, 4.0f); -} - -void ScreenLensDistortionOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - set_determined_canvas_modifier([=](rcti &canvas) { - /* Ensure screen space. */ - BLI_rcti_translate(&canvas, -canvas.xmin, -canvas.ymin); - }); - - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void ScreenLensDistortionOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - if (input_idx != 0) { - /* Dispersion and distortion inputs are used as constants only. */ - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - } - - /* XXX the original method of estimating the area-of-interest does not work - * it assumes a linear increase/decrease of mapped coordinates, which does not - * yield correct results for the area and leaves uninitialized buffer areas. - * So now just use the full image area, which may not be as efficient but works at least ... - */ - NodeOperation *image = get_input_operation(0); - r_input_area = image->get_canvas(); -} - -void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_image = inputs[0]; - if (input_image->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input_image->get_elem(0, 0)); - return; - } - for (BuffersIterator it = output->iterate_with({}, area); !it.is_end(); ++it) { - float xy[2] = {float(it.x), float(it.y)}; - float uv[2]; - get_uv(xy, uv); - const float uv_dot = len_squared_v2(uv); - - float delta[3][2]; - const bool valid_r = get_delta(uv_dot, k4_[0], uv, delta[0]); - const bool valid_g = get_delta(uv_dot, k4_[1], uv, delta[1]); - const bool valid_b = get_delta(uv_dot, k4_[2], uv, delta[2]); - if (!(valid_r && valid_g && valid_b)) { - zero_v4(it.out); - continue; - } - - int count[3] = {0, 0, 0}; - float sum[4] = {0, 0, 0, 0}; - accumulate(input_image, 0, 1, uv_dot, uv, delta, sum, count); - accumulate(input_image, 1, 2, uv_dot, uv, delta, sum, count); - - if (count[0]) { - it.out[0] = 2.0f * sum[0] / float(count[0]); - } - if (count[1]) { - it.out[1] = 2.0f * sum[1] / float(count[1]); - } - if (count[2]) { - it.out[2] = 2.0f * sum[2] / float(count[2]); - } - - /* Set alpha. */ - it.out[3] = 1.0f; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h deleted file mode 100644 index c261c37d39e..00000000000 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_node_types.h" - -struct RNG; - -namespace blender::compositor { - -class ScreenLensDistortionOperation : public MultiThreadedOperation { - private: - struct RNG *rng_; - - bool fit_; - bool jitter_; - - float dispersion_; - float distortion_; - bool dispersion_const_; - bool distortion_const_; - bool variables_ready_; - float k_[3]; - float k4_[3]; - float dk4_[3]; - float maxk_; - float sc_, cx_, cy_; - - public: - ScreenLensDistortionOperation(); - - void init_data() override; - - void init_execution() override; - void deinit_execution() override; - - void set_fit(bool fit) - { - fit_ = fit; - } - void set_jitter(bool jitter) - { - jitter_ = jitter; - } - - /** Set constant distortion value */ - void set_distortion(float distortion); - /** Set constant dispersion value */ - void set_dispersion(float dispersion); - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - 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 inputs) override; - - private: - void determineUV(float result[6], float x, float y) const; - void update_variables(float distortion, float dispersion); - - void get_uv(const float xy[2], float uv[2]) const; - void distort_uv(const float uv[2], float t, float xy[2]) const; - bool get_delta(float r_sq, float k4, const float uv[2], float delta[2]) const; - void accumulate(const MemoryBuffer *buffer, - int a, - int b, - float r_sq, - const float uv[2], - const float delta[3][2], - float sum[4], - int count[3]) const; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.cc b/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.cc deleted file mode 100644 index 7d26407ce42..00000000000 --- a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetAlphaMultiplyOperation.h" - -namespace blender::compositor { - -SetAlphaMultiplyOperation::SetAlphaMultiplyOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; -} - -void SetAlphaMultiplyOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - const float alpha = *it.in(1); - mul_v4_v4fl(it.out, color, alpha); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h b/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h deleted file mode 100644 index b1eb1b51b9c..00000000000 --- a/source/blender/compositor/operations/COM_SetAlphaMultiplyOperation.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * This operation will apply a mask to its input image. - * - * `output color.rgba = input color.rgba * input alpha` - */ -class SetAlphaMultiplyOperation : public MultiThreadedOperation { - public: - SetAlphaMultiplyOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.cc b/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.cc deleted file mode 100644 index d0c12c251a7..00000000000 --- a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetAlphaReplaceOperation.h" - -namespace blender::compositor { - -SetAlphaReplaceOperation::SetAlphaReplaceOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; -} - -void SetAlphaReplaceOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float *color = it.in(0); - const float alpha = *it.in(1); - copy_v3_v3(it.out, color); - it.out[3] = alpha; - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h b/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h deleted file mode 100644 index 899b056bffa..00000000000 --- a/source/blender/compositor/operations/COM_SetAlphaReplaceOperation.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class SetAlphaReplaceOperation : public MultiThreadedOperation { - public: - SetAlphaReplaceOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cc b/source/blender/compositor/operations/COM_SetColorOperation.cc deleted file mode 100644 index 0a218e8b843..00000000000 --- a/source/blender/compositor/operations/COM_SetColorOperation.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetColorOperation.h" - -namespace blender::compositor { - -SetColorOperation::SetColorOperation() -{ - this->add_output_socket(DataType::Color); - flags_.is_constant_operation = true; -} - -void SetColorOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h deleted file mode 100644 index 30a9774a9bc..00000000000 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class SetColorOperation : public ConstantOperation { - private: - float color_[4]; - - public: - /** - * Default constructor - */ - SetColorOperation(); - - const float *get_constant_elem() override - { - return color_; - } - - float get_channel1() - { - return color_[0]; - } - void set_channel1(float value) - { - color_[0] = value; - } - float get_channel2() - { - return color_[1]; - } - void set_channel2(float value) - { - color_[1] = value; - } - float get_channel3() - { - return color_[2]; - } - void set_channel3(float value) - { - color_[2] = value; - } - float get_channel4() - { - return color_[3]; - } - void set_channel4(const float value) - { - color_[3] = value; - } - void set_channels(const float value[4]) - { - copy_v4_v4(color_, value); - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cc b/source/blender/compositor/operations/COM_SetSamplerOperation.cc deleted file mode 100644 index c1fc0793d8d..00000000000 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetSamplerOperation.h" - -namespace blender::compositor { - -SetSamplerOperation::SetSamplerOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h deleted file mode 100644 index 17e28bd3006..00000000000 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output Sampler. - * it assumes we are in sRGB color space. - */ -class SetSamplerOperation : public NodeOperation { - private: - PixelSampler sampler_; - - public: - SetSamplerOperation(); - - void set_sampler(PixelSampler sampler) - { - sampler_ = sampler; - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cc b/source/blender/compositor/operations/COM_SetValueOperation.cc deleted file mode 100644 index 655bc7bf6a3..00000000000 --- a/source/blender/compositor/operations/COM_SetValueOperation.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetValueOperation.h" - -namespace blender::compositor { - -SetValueOperation::SetValueOperation() -{ - this->add_output_socket(DataType::Value); - flags_.is_constant_operation = true; -} - -void SetValueOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h deleted file mode 100644 index 9f503ab9d17..00000000000 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class SetValueOperation : public ConstantOperation { - private: - float value_; - - public: - /** - * Default constructor - */ - SetValueOperation(); - - const float *get_constant_elem() override - { - return &value_; - } - - float get_value() - { - return value_; - } - void set_value(float value) - { - value_ = value; - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cc b/source/blender/compositor/operations/COM_SetVectorOperation.cc deleted file mode 100644 index 471345ce879..00000000000 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SetVectorOperation.h" - -namespace blender::compositor { - -SetVectorOperation::SetVectorOperation() -{ - this->add_output_socket(DataType::Vector); - flags_.is_constant_operation = true; -} - -void SetVectorOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h deleted file mode 100644 index d91ca9a894e..00000000000 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_ConstantOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class SetVectorOperation : public ConstantOperation { - private: - struct { - float x; - float y; - float z; - float w; - } vector_; - - public: - /** - * Default constructor - */ - SetVectorOperation(); - - const float *get_constant_elem() override - { - return reinterpret_cast(&vector_); - } - - float getX() - { - return vector_.x; - } - void setX(float value) - { - vector_.x = value; - } - float getY() - { - return vector_.y; - } - void setY(float value) - { - vector_.y = value; - } - float getZ() - { - return vector_.z; - } - void setZ(float value) - { - vector_.z = value; - } - float getW() - { - return vector_.w; - } - void setW(float value) - { - vector_.w = value; - } - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_vector(const float vector[3]) - { - setX(vector[0]); - setY(vector[1]); - setZ(vector[2]); - } -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cc b/source/blender/compositor/operations/COM_SocketProxyOperation.cc deleted file mode 100644 index 053449267cc..00000000000 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SocketProxyOperation.h" - -namespace blender::compositor { - -SocketProxyOperation::SocketProxyOperation(DataType type, bool use_conversion) -{ - this->add_input_socket(type); - this->add_output_socket(type); - flags_.is_proxy_operation = true; - flags_.use_datatype_conversion = use_conversion; -} - -std::unique_ptr SocketProxyOperation::get_meta_data() -{ - return this->get_input_socket(0)->get_reader()->get_meta_data(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h deleted file mode 100644 index d6fe9c293dd..00000000000 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -class SocketProxyOperation : public NodeOperation { - public: - SocketProxyOperation(DataType type, bool use_conversion); - - std::unique_ptr get_meta_data() override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SplitOperation.cc b/source/blender/compositor/operations/COM_SplitOperation.cc deleted file mode 100644 index add20b80844..00000000000 --- a/source/blender/compositor/operations/COM_SplitOperation.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_SplitOperation.h" - -namespace blender::compositor { - -SplitOperation::SplitOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; -} - -void SplitOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - rcti unused_area = COM_AREA_NONE; - - const bool determined = this->get_input_socket(0)->determine_canvas(COM_AREA_NONE, unused_area); - this->set_canvas_input_index(determined ? 0 : 1); - - NodeOperation::determine_canvas(preferred_area, r_area); -} - -void SplitOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const int percent = x_split_ ? split_percentage_ * this->get_width() / 100.0f : - split_percentage_ * this->get_height() / 100.0f; - const size_t elem_bytes = COM_data_type_bytes_len(get_output_socket()->get_data_type()); - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const bool is_image1 = x_split_ ? it.x >= percent : it.y >= percent; - memcpy(it.out, it.in(is_image1 ? 0 : 1), elem_bytes); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SplitOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h deleted file mode 100644 index ff5ea9e4683..00000000000 --- a/source/blender/compositor/operations/COM_SplitOperation.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class SplitOperation : public MultiThreadedOperation { - private: - float split_percentage_; - bool x_split_; - - public: - SplitOperation(); - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - void set_split_percentage(float split_percentage) - { - split_percentage_ = split_percentage; - } - void set_xsplit(bool xsplit) - { - x_split_ = xsplit; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc b/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc deleted file mode 100644 index 7e93be96e13..00000000000 --- a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" -#include "BLI_task.hh" - -#include "COM_SummedAreaTableOperation.h" - -namespace blender::compositor { - -SummedAreaTableOperation::SummedAreaTableOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - - mode_ = eMode::Identity; - - this->flags_.can_be_constant = true; -} - -void SummedAreaTableOperation::get_area_of_interest(int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - r_input_area = get_input_operation(input_idx)->get_canvas(); -} - -void SummedAreaTableOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - /* NOTE: although this is a single threaded call, multithreading is used. */ - MemoryBuffer *image = inputs[0]; - - /* First pass: copy input to output and sum horizontally. */ - threading::parallel_for( - IndexRange(area.ymin, area.ymax - area.ymin), 1, [&](const IndexRange range_y) { - for (const int y : range_y) { - float4 accumulated_color = float4(0.0f); - for (const int x : IndexRange(area.xmin, area.xmax - area.xmin)) { - const float4 color = float4(image->get_elem(x, y)); - accumulated_color += mode_ == eMode::Squared ? color * color : color; - copy_v4_v4(output->get_elem(x, y), accumulated_color); - } - } - }); - - /* Second pass: vertical sum. */ - threading::parallel_for( - IndexRange(area.xmin, area.xmax - area.xmin), 1, [&](const IndexRange range_x) { - for (const int x : range_x) { - float4 accumulated_color = float4(0.0f); - for (const int y : IndexRange(area.ymin, area.ymax - area.ymin)) { - const float4 color = float4(output->get_elem(x, y)); - accumulated_color += color; - copy_v4_v4(output->get_elem(x, y), accumulated_color); - } - } - }); -} - -void SummedAreaTableOperation::set_mode(eMode mode) -{ - mode_ = mode; -} - -SummedAreaTableOperation::eMode SummedAreaTableOperation::get_mode() -{ - return mode_; -} - -float4 summed_area_table_sum(MemoryBuffer *buffer, const rcti &area) -{ - /* - * a, b, c and d are the bounding box of the given area. They are defined as follows: - * - * y - * â–² - * │ - * ├──────x───────x - * │ │c d│ - * ├──────x───────x - * │ │a b│ - * └──────┴───────┴──────► x - * - * NOTE: this is the same definition as in https://en.wikipedia.org/wiki/Summed-area_table - * but using the blender convention with the origin being at the lower left. - */ - - BLI_assert(area.xmin <= area.xmax && area.ymin <= area.ymax); - - int2 lower_bound(area.xmin, area.ymin); - int2 upper_bound(area.xmax, area.ymax); - - int2 corrected_lower_bound = lower_bound - int2(1, 1); - int2 corrected_upper_bound; - corrected_upper_bound[0] = math::min(buffer->get_width() - 1, upper_bound[0]); - corrected_upper_bound[1] = math::min(buffer->get_height() - 1, upper_bound[1]); - - float4 a, b, c, d, addend, substrahend; - buffer->read_elem_checked(corrected_upper_bound[0], corrected_upper_bound[1], a); - buffer->read_elem_checked(corrected_lower_bound[0], corrected_lower_bound[1], d); - addend = a + d; - - buffer->read_elem_checked(corrected_lower_bound[0], corrected_upper_bound[1], b); - buffer->read_elem_checked(corrected_upper_bound[0], corrected_lower_bound[1], c); - substrahend = b + c; - - float4 sum = addend - substrahend; - - return sum; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SummedAreaTableOperation.h b/source/blender/compositor/operations/COM_SummedAreaTableOperation.h deleted file mode 100644 index 37bab63478a..00000000000 --- a/source/blender/compositor/operations/COM_SummedAreaTableOperation.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" - -namespace blender::compositor { - -/** - * \brief SummedAreaTableOperation class computes the summed area table. - */ -class SummedAreaTableOperation : public NodeOperation { - - public: - SummedAreaTableOperation(); - - enum eMode { Identity = 1, Squared }; - - void set_mode(const eMode mode); - eMode get_mode(); - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - eMode mode_; -}; - -/* Computes the sum of the rectangular region defined by the given area from the - * given summed area table. All coordinates within the area are included. */ -float4 summed_area_table_sum(MemoryBuffer *buffer, const rcti &area); - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cc b/source/blender/compositor/operations/COM_SunBeamsOperation.cc deleted file mode 100644 index 64d1561b879..00000000000 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_base.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_math_vector_types.hh" - -#include "MEM_guardedalloc.h" - -#include "COM_SunBeamsOperation.h" - -namespace blender::compositor { - -SunBeamsOperation::SunBeamsOperation() -{ - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - this->set_canvas_input_index(0); -} - -void SunBeamsOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input = inputs[0]; - - const float2 input_size = float2(input->get_width(), input->get_height()); - const int max_steps = int(data_.ray_length * math::length(input_size)); - const float2 source = float2(data_.source); - - for (int y = area.ymin; y < area.ymax; y++) { - for (int x = area.xmin; x < area.xmax; x++) { - if (max_steps == 0) { - copy_v4_v4(output->get_elem(x, y), input->get_elem(x, y)); - continue; - } - - const float2 texel = float2(x, y); - - /* The number of steps is the distance in pixels from the source to the current texel. With - * at least a single step and at most the user specified maximum ray length, which is - * proportional to the diagonal pixel count. */ - const float unbounded_steps = math::max(1.0f, math::distance(texel, source * input_size)); - const int steps = math::min(max_steps, int(unbounded_steps)); - - /* We integrate from the current pixel to the source pixel, so compute the start coordinates - * and step vector in the direction to source. Notice that the step vector is still computed - * from the unbounded steps, such that the total integration length becomes limited by the - * bounded steps, and thus by the maximum ray length. */ - const float2 coordinates = (texel + float2(0.5f)) / input_size; - const float2 vector_to_source = source - coordinates; - const float2 step_vector = vector_to_source / unbounded_steps; - - float accumulated_weight = 0.0f; - float4 accumulated_color = float4(0.0f); - for (int i = 0; i <= steps; i++) { - float2 position = coordinates + i * step_vector; - - /* We are already past the image boundaries, and any future steps are also past the image - * boundaries, so break. */ - if (position.x < 0.0f || position.y < 0.0f || position.x > 1.0f || position.y > 1.0f) { - break; - } - - const float4 sample_color = input->texture_bilinear_extend(position); - - /* Attenuate the contributions of pixels that are further away from the source using a - * quadratic falloff. */ - const float weight = math::square(1.0f - i / float(steps)); - - accumulated_weight += weight; - accumulated_color += sample_color * weight; - } - - accumulated_color /= accumulated_weight != 0.0f ? accumulated_weight : 1.0f; - copy_v4_v4(output->get_elem(x, y), accumulated_color); - } - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h deleted file mode 100644 index b9afe0faa4d..00000000000 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-FileCopyrightText: 2014 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class SunBeamsOperation : public MultiThreadedOperation { - public: - SunBeamsOperation(); - - void set_data(const NodeSunBeams &data) - { - data_ = data; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - private: - NodeSunBeams data_; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TextureOperation.cc b/source/blender/compositor/operations/COM_TextureOperation.cc deleted file mode 100644 index 2b034d4595e..00000000000 --- a/source/blender/compositor/operations/COM_TextureOperation.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TextureOperation.h" -#include "COM_WorkScheduler.h" - -#include "BKE_image.hh" -#include "BKE_node.hh" -#include "BKE_scene.hh" - -#include "NOD_texture.h" - -namespace blender::compositor { - -TextureBaseOperation::TextureBaseOperation() -{ - this->add_input_socket(DataType::Vector); // offset - this->add_input_socket(DataType::Vector); // size - texture_ = nullptr; - rd_ = nullptr; - pool_ = nullptr; - scene_color_manage_ = false; -} -TextureOperation::TextureOperation() : TextureBaseOperation() -{ - this->add_output_socket(DataType::Color); -} -TextureAlphaOperation::TextureAlphaOperation() : TextureBaseOperation() -{ - this->add_output_socket(DataType::Value); -} - -void TextureBaseOperation::init_execution() -{ - pool_ = BKE_image_pool_new(); - if (texture_ != nullptr && texture_->nodetree != nullptr && texture_->use_nodes) { - ntreeTexBeginExecTree(texture_->nodetree); - } - NodeOperation::init_execution(); -} -void TextureBaseOperation::deinit_execution() -{ - BKE_image_pool_free(pool_); - pool_ = nullptr; - if (texture_ != nullptr && texture_->use_nodes && texture_->nodetree != nullptr && - texture_->nodetree->runtime->execdata != nullptr) - { - ntreeTexEndExecTree(texture_->nodetree->runtime->execdata); - } - NodeOperation::deinit_execution(); -} - -void TextureBaseOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; - if (BLI_rcti_is_empty(&preferred_area)) { - int width, height; - BKE_render_resolution(rd_, false, &width, &height); - r_area.xmax = preferred_area.xmin + width; - r_area.ymax = preferred_area.ymin + height; - } - - /* Determine inputs. */ - rcti temp = COM_AREA_NONE; - NodeOperation::determine_canvas(r_area, temp); -} - -void TextureBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const float3 offset = inputs[0]->get_elem(0, 0); - const float3 scale = inputs[1]->get_elem(0, 0); - const int2 size = int2(this->get_width(), this->get_height()); - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - /* Compute the coordinates in the [-1, 1] range and add 0.5 to evaluate the texture at the - * center of pixels in case it was interpolated. */ - const float2 pixel_coordinates = ((float2(it.x, it.y) + 0.5f) / float2(size)) * 2.0f - 1.0f; - /* Note that it is expected that the offset is scaled by the scale. */ - const float3 coordinates = (float3(pixel_coordinates, 0.0f) + offset) * scale; - - TexResult texture_result; - const int result_type = multitex_ext(texture_, - coordinates, - nullptr, - nullptr, - 0, - &texture_result, - WorkScheduler::current_thread_id(), - pool_, - scene_color_manage_, - false); - - float4 color = float4(texture_result.trgba); - color.w = texture_result.talpha ? color.w : texture_result.tin; - if (!(result_type & TEX_RGB)) { - copy_v3_fl(color, color.w); - } - copy_v4_v4(it.out, color); - } -} - -void TextureAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer texture(DataType::Color, area); - TextureBaseOperation::update_memory_buffer_partial(&texture, area, inputs); - output->copy_from(&texture, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h deleted file mode 100644 index 51bd5aa8d0e..00000000000 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_listbase.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_texture_types.h" -#include "MEM_guardedalloc.h" - -#include "RE_pipeline.h" -#include "RE_texture.h" - -namespace blender::compositor { - -/** - * Base class for all renderlayeroperations - * - * \todo Rename to operation. - */ -class TextureBaseOperation : public MultiThreadedOperation { - private: - Tex *texture_; - const RenderData *rd_; - struct ImagePool *pool_; - bool scene_color_manage_; - - protected: - /** - * Determine the output resolution. - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - /** - * Constructor - */ - TextureBaseOperation(); - - public: - void set_texture(Tex *texture) - { - texture_ = texture; - } - void init_execution() override; - void deinit_execution() override; - void set_render_data(const RenderData *rd) - { - rd_ = rd; - } - void set_scene_color_manage(bool scene_color_manage) - { - scene_color_manage_ = scene_color_manage; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class TextureOperation : public TextureBaseOperation { - public: - TextureOperation(); -}; -class TextureAlphaOperation : public TextureBaseOperation { - public: - TextureAlphaOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc deleted file mode 100644 index bea0b03b1c7..00000000000 --- a/source/blender/compositor/operations/COM_TonemapOperation.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TonemapOperation.h" - -#include "COM_ExecutionSystem.h" - -#include "IMB_colormanagement.hh" - -namespace blender::compositor { - -TonemapOperation::TonemapOperation() -{ - this->add_input_socket(DataType::Color, ResizeMode::Align); - this->add_output_socket(DataType::Color); - data_ = nullptr; - cached_instance_ = nullptr; - flags_.can_be_constant = true; -} - -void TonemapOperation::get_area_of_interest(const int input_idx, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - BLI_assert(input_idx == 0); - r_input_area = get_input_operation(input_idx)->get_canvas(); -} - -struct Luminance { - float sum; - float color_sum[3]; - float log_sum; - float min; - float max; - int num_pixels; -}; - -static Luminance calc_area_luminance(const MemoryBuffer *input, const rcti &area) -{ - Luminance lum = {0}; - for (const float *elem : input->get_buffer_area(area)) { - const float lu = IMB_colormanagement_get_luminance(elem); - lum.sum += lu; - add_v3_v3(lum.color_sum, elem); - lum.log_sum += logf(std::max(lu, 0.0f) + 1e-5f); - lum.max = std::max(lu, lum.max); - lum.min = std::min(lu, lum.min); - lum.num_pixels++; - } - return lum; -} - -void TonemapOperation::update_memory_buffer_started(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - MemoryBuffer *input_img = inputs[0]; - if (input_img->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input_img->get_elem(0, 0)); - return; - } - - if (cached_instance_ == nullptr) { - Luminance lum = {0}; - const MemoryBuffer *input = inputs[0]; - exec_system_->execute_work( - input->get_rect(), - [=](const rcti &split) { return calc_area_luminance(input, split); }, - lum, - [](Luminance &join, const Luminance &chunk) { - join.sum += chunk.sum; - add_v3_v3(join.color_sum, chunk.color_sum); - join.log_sum += chunk.log_sum; - join.max = std::max(join.max, chunk.max); - join.min = std::min(join.min, chunk.min); - join.num_pixels += chunk.num_pixels; - }); - - AvgLogLum *avg = new AvgLogLum(); - avg->lav = lum.sum / lum.num_pixels; - mul_v3_v3fl(avg->cav, lum.color_sum, 1.0f / lum.num_pixels); - const float max_log = log(double(lum.max) + 1e-5); - const float min_log = log(double(lum.min) + 1e-5); - const float avg_log = lum.log_sum / lum.num_pixels; - avg->auto_key = (max_log > min_log) ? ((max_log - avg_log) / (max_log - min_log)) : 1.0f; - const float al = exp(double(avg_log)); - avg->al = (al == 0.0f) ? 0.0f : (data_->key / al); - avg->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma); - cached_instance_ = avg; - } -} - -void TonemapOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input_img = inputs[0]; - - if (input_img->is_a_single_elem()) { - return; - } - - AvgLogLum *avg = cached_instance_; - const float igm = avg->igm; - const float offset = data_->offset; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - copy_v4_v4(it.out, it.in(0)); - mul_v3_fl(it.out, avg->al); - float dr = it.out[0] + offset; - float dg = it.out[1] + offset; - float db = it.out[2] + offset; - it.out[0] /= ((dr == 0.0f) ? 1.0f : dr); - it.out[1] /= ((dg == 0.0f) ? 1.0f : dg); - it.out[2] /= ((db == 0.0f) ? 1.0f : db); - if (igm != 0.0f) { - it.out[0] = powf(std::max(it.out[0], 0.0f), igm); - it.out[1] = powf(std::max(it.out[1], 0.0f), igm); - it.out[2] = powf(std::max(it.out[2], 0.0f), igm); - } - } -} - -void PhotoreceptorTonemapOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input_img = inputs[0]; - if (input_img->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input_img->get_elem(0, 0)); - return; - } - - AvgLogLum *avg = cached_instance_; - const NodeTonemap *ntm = data_; - const float f = expf(-data_->f); - const float m = (ntm->m > 0.0f) ? ntm->m : (0.3f + 0.7f * powf(avg->auto_key, 1.4f)); - const float ic = 1.0f - ntm->c; - const float ia = 1.0f - ntm->a; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - copy_v4_v4(it.out, it.in(0)); - const float L = IMB_colormanagement_get_luminance(it.out); - float I_l = it.out[0] + ic * (L - it.out[0]); - float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]); - float I_a = I_l + ia * (I_g - I_l); - it.out[0] /= (it.out[0] + powf(f * I_a, m)); - I_l = it.out[1] + ic * (L - it.out[1]); - I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]); - I_a = I_l + ia * (I_g - I_l); - it.out[1] /= (it.out[1] + powf(f * I_a, m)); - I_l = it.out[2] + ic * (L - it.out[2]); - I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]); - I_a = I_l + ia * (I_g - I_l); - it.out[2] /= (it.out[2] + powf(f * I_a, m)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h deleted file mode 100644 index 6254c9177bd..00000000000 --- a/source/blender/compositor/operations/COM_TonemapOperation.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -/** - * \brief temporarily storage during execution of Tone-map - * \ingroup operation - */ -typedef struct AvgLogLum { - float al; - float auto_key; - float lav; - float cav[4]; - float igm; -} AvgLogLum; - -/** - * \brief base class of tone-map, implementing the simple tone-map - * \ingroup operation - */ -class TonemapOperation : public MultiThreadedOperation { - protected: - /** - * \brief settings of the Tone-map - */ - const NodeTonemap *data_; - - /** - * \brief temporarily cache of the execution storage - */ - AvgLogLum *cached_instance_; - - public: - TonemapOperation(); - - void set_data(const NodeTonemap *data) - { - data_ = data; - } - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - virtual void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -/** - * \brief class of tone-map, implementing the photo-receptor tone-map - * most parts have already been done in #TonemapOperation. - * \ingroup operation - */ -class PhotoreceptorTonemapOperation : public TonemapOperation { - public: - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cc b/source/blender/compositor/operations/COM_TrackPositionOperation.cc deleted file mode 100644 index 7a0a37d889f..00000000000 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TrackPositionOperation.h" - -#include "DNA_defaults.h" - -#include "BKE_movieclip.h" -#include "BKE_node.hh" -#include "BKE_tracking.h" - -namespace blender::compositor { - -TrackPositionOperation::TrackPositionOperation() -{ - this->add_output_socket(DataType::Value); - movie_clip_ = nullptr; - framenumber_ = 0; - tracking_object_name_[0] = 0; - track_name_[0] = 0; - axis_ = 0; - position_ = CMP_NODE_TRACK_POSITION_ABSOLUTE; - relative_frame_ = 0; - speed_output_ = false; - flags_.is_constant_operation = true; - is_track_position_calculated_ = false; -} - -void TrackPositionOperation::init_execution() -{ - if (!is_track_position_calculated_) { - calc_track_position(); - } -} - -void TrackPositionOperation::calc_track_position() -{ - is_track_position_calculated_ = true; - MovieClipUser user = *DNA_struct_default_get(MovieClipUser); - - track_position_ = 0; - zero_v2(marker_pos_); - zero_v2(relative_pos_); - - if (!movie_clip_) { - return; - } - - MovieTracking *tracking = &movie_clip_->tracking; - - BKE_movieclip_user_set_frame(&user, framenumber_); - BKE_movieclip_get_size(movie_clip_, &user, &width_, &height_); - - MovieTrackingObject *tracking_object = BKE_tracking_object_get_named(tracking, - tracking_object_name_); - if (tracking_object) { - MovieTrackingTrack *track = BKE_tracking_object_find_track_with_name(tracking_object, - track_name_); - - if (track) { - MovieTrackingMarker *marker; - int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, framenumber_); - - marker = BKE_tracking_marker_get(track, clip_framenr); - - copy_v2_v2(marker_pos_, marker->pos); - - if (speed_output_) { - int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, - relative_frame_); - - marker = BKE_tracking_marker_get_exact(track, relative_clip_framenr); - if (marker != nullptr && (marker->flag & MARKER_DISABLED) == 0) { - copy_v2_v2(relative_pos_, marker->pos); - } - else { - copy_v2_v2(relative_pos_, marker_pos_); - } - if (relative_frame_ < framenumber_) { - swap_v2_v2(relative_pos_, marker_pos_); - } - } - else if (position_ == CMP_NODE_TRACK_POSITION_RELATIVE_START) { - int i; - - for (i = 0; i < track->markersnr; i++) { - marker = &track->markers[i]; - - if ((marker->flag & MARKER_DISABLED) == 0) { - copy_v2_v2(relative_pos_, marker->pos); - - break; - } - } - } - else if (position_ == CMP_NODE_TRACK_POSITION_RELATIVE_FRAME) { - int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movie_clip_, - relative_frame_); - - marker = BKE_tracking_marker_get(track, relative_clip_framenr); - copy_v2_v2(relative_pos_, marker->pos); - } - } - } - - track_position_ = marker_pos_[axis_] - relative_pos_[axis_]; - if (axis_ == 0) { - track_position_ *= width_; - } - else { - track_position_ *= height_; - } -} - -const float *TrackPositionOperation::get_constant_elem() -{ - if (!is_track_position_calculated_) { - calc_track_position(); - } - return &track_position_; -} - -void TrackPositionOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - r_area = preferred_area; -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h deleted file mode 100644 index 0421185d4db..00000000000 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SPDX-FileCopyrightText: 2012 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include - -#include "COM_ConstantOperation.h" - -#include "DNA_movieclip_types.h" -#include "DNA_tracking_types.h" - -#include "BLI_listbase.h" -#include "BLI_string.h" - -namespace blender::compositor { - -/** - * Class with implementation of green screen gradient rasterization - */ -class TrackPositionOperation : public ConstantOperation { - protected: - MovieClip *movie_clip_; - int framenumber_; - char tracking_object_name_[64]; - char track_name_[64]; - int axis_; - CMPNodeTrackPositionMode position_; - int relative_frame_; - bool speed_output_; - - int width_, height_; - float marker_pos_[2]; - float relative_pos_[2]; - float track_position_; - bool is_track_position_calculated_; - - /** - * Determine the output resolution. The resolution is retrieved from the Renderer - */ - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - public: - TrackPositionOperation(); - - void set_movie_clip(MovieClip *clip) - { - movie_clip_ = clip; - } - void set_tracking_object(char *object) - { - BLI_strncpy(tracking_object_name_, object, sizeof(tracking_object_name_)); - } - void set_track_name(char *track) - { - BLI_strncpy(track_name_, track, sizeof(track_name_)); - } - void set_framenumber(int framenumber) - { - framenumber_ = framenumber; - } - void set_axis(int value) - { - axis_ = value; - } - void set_position(CMPNodeTrackPositionMode value) - { - position_ = value; - } - void set_relative_frame(int value) - { - relative_frame_ = value; - } - void set_speed_output(bool speed_output) - { - speed_output_ = speed_output; - } - - void init_execution() override; - - const float *get_constant_elem() override; - - private: - void calc_track_position(); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TransformOperation.cc b/source/blender/compositor/operations/COM_TransformOperation.cc deleted file mode 100644 index 8db041dea42..00000000000 --- a/source/blender/compositor/operations/COM_TransformOperation.cc +++ /dev/null @@ -1,203 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TransformOperation.h" -#include "BLI_math_rotation.h" -#include "COM_RotateOperation.h" -#include "COM_ScaleOperation.h" - -namespace blender::compositor { - -TransformOperation::TransformOperation() -{ - add_input_socket(DataType::Color, ResizeMode::None); - add_input_socket(DataType::Value, ResizeMode::None); - add_input_socket(DataType::Value, ResizeMode::None); - add_input_socket(DataType::Value, ResizeMode::None); - add_input_socket(DataType::Value, ResizeMode::None); - add_output_socket(DataType::Color); - translate_factor_x_ = 1.0f; - translate_factor_y_ = 1.0f; - convert_degree_to_rad_ = false; - sampler_ = PixelSampler::Bilinear; - invert_ = false; - - flags_.can_be_constant = true; -} - -void TransformOperation::init_data() -{ - - translate_x_ = get_input_operation(X_INPUT_INDEX)->get_constant_value_default(0.0f) * - translate_factor_x_; - translate_y_ = get_input_operation(Y_INPUT_INDEX)->get_constant_value_default(0.0f) * - translate_factor_y_; - - const float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f); - const double rad = convert_degree_to_rad_ ? DEG2RAD(double(degree)) : degree; - rotate_cosine_ = cos(rad); - rotate_sine_ = sin(rad); - - scale_ = get_input_operation(SCALE_INPUT_INDEX)->get_constant_value_default(1.0f); -} - -void TransformOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: { - NodeOperation *image_op = get_input_operation(IMAGE_INPUT_INDEX); - const rcti &image_canvas = image_op->get_canvas(); - if (invert_) { - /* Scale -> Rotate -> Translate. */ - r_input_area = output_area; - BLI_rcti_translate(&r_input_area, -translate_x_, -translate_y_); - RotateOperation::get_rotation_area_of_interest(scale_canvas_, - rotate_canvas_, - rotate_sine_, - rotate_cosine_, - r_input_area, - r_input_area); - ScaleOperation::get_scale_area_of_interest( - image_canvas, scale_canvas_, scale_, scale_, r_input_area, r_input_area); - } - else { - /* Translate -> Rotate -> Scale. */ - ScaleOperation::get_scale_area_of_interest( - rotate_canvas_, scale_canvas_, scale_, scale_, output_area, r_input_area); - RotateOperation::get_rotation_area_of_interest(translate_canvas_, - rotate_canvas_, - rotate_sine_, - rotate_cosine_, - r_input_area, - r_input_area); - BLI_rcti_translate(&r_input_area, -translate_x_, -translate_y_); - } - expand_area_for_sampler(r_input_area, sampler_); - break; - } - case X_INPUT_INDEX: - case Y_INPUT_INDEX: - case DEGREE_INPUT_INDEX: - case SCALE_INPUT_INDEX: { - r_input_area = COM_CONSTANT_INPUT_AREA_OF_INTEREST; - break; - } - } -} - -void TransformOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - const MemoryBuffer *input_img = inputs[IMAGE_INPUT_INDEX]; - BuffersIterator it = output->iterate_with({}, area); - if (invert_) { - transform_inverted(it, input_img); - } - else { - transform(it, input_img); - } -} - -void TransformOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - const bool image_determined = - get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area); - if (image_determined) { - rcti image_canvas = r_area; - rcti unused = COM_AREA_NONE; - get_input_socket(X_INPUT_INDEX)->determine_canvas(image_canvas, unused); - get_input_socket(Y_INPUT_INDEX)->determine_canvas(image_canvas, unused); - get_input_socket(DEGREE_INPUT_INDEX)->determine_canvas(image_canvas, unused); - get_input_socket(SCALE_INPUT_INDEX)->determine_canvas(image_canvas, unused); - - init_data(); - if (invert_) { - /* Scale -> Rotate -> Translate. */ - scale_canvas_ = image_canvas; - ScaleOperation::scale_area(scale_canvas_, scale_, scale_); - - RotateOperation::get_rotation_canvas( - scale_canvas_, rotate_sine_, rotate_cosine_, rotate_canvas_); - - translate_canvas_ = rotate_canvas_; - BLI_rcti_translate(&translate_canvas_, translate_x_, translate_y_); - - r_area = translate_canvas_; - } - else { - /* Translate -> Rotate -> Scale. */ - translate_canvas_ = image_canvas; - BLI_rcti_translate(&translate_canvas_, translate_x_, translate_y_); - - RotateOperation::get_rotation_canvas( - translate_canvas_, rotate_sine_, rotate_cosine_, rotate_canvas_); - - scale_canvas_ = rotate_canvas_; - ScaleOperation::scale_area(scale_canvas_, scale_, scale_); - - r_area = scale_canvas_; - } - } -} - -void TransformOperation::transform(BuffersIterator &it, const MemoryBuffer *input_img) -{ - float rotate_center_x, rotate_center_y; - RotateOperation::get_rotation_center(translate_canvas_, rotate_center_x, rotate_center_y); - float rotate_offset_x, rotate_offset_y; - RotateOperation::get_rotation_offset( - translate_canvas_, rotate_canvas_, rotate_offset_x, rotate_offset_y); - - const float scale_center_x = BLI_rcti_size_x(&rotate_canvas_) / 2.0f; - const float scale_center_y = BLI_rcti_size_y(&rotate_canvas_) / 2.0f; - float scale_offset_x, scale_offset_y; - ScaleOperation::get_scale_offset(rotate_canvas_, scale_canvas_, scale_offset_x, scale_offset_y); - - for (; !it.is_end(); ++it) { - float x = ScaleOperation::scale_coord_inverted(it.x + scale_offset_x, scale_center_x, scale_); - float y = ScaleOperation::scale_coord_inverted(it.y + scale_offset_y, scale_center_y, scale_); - - x = rotate_offset_x + x; - y = rotate_offset_y + y; - RotateOperation::rotate_coords( - x, y, rotate_center_x, rotate_center_y, rotate_sine_, rotate_cosine_); - - input_img->read_elem_sampled(x - translate_x_, y - translate_y_, sampler_, it.out); - } -} - -void TransformOperation::transform_inverted(BuffersIterator &it, - const MemoryBuffer *input_img) -{ - const rcti &image_canvas = get_input_operation(IMAGE_INPUT_INDEX)->get_canvas(); - const float scale_center_x = BLI_rcti_size_x(&image_canvas) / 2.0f - translate_x_; - const float scale_center_y = BLI_rcti_size_y(&image_canvas) / 2.0f - translate_y_; - float scale_offset_x, scale_offset_y; - ScaleOperation::get_scale_offset(image_canvas, scale_canvas_, scale_offset_x, scale_offset_y); - - float rotate_center_x, rotate_center_y; - RotateOperation::get_rotation_center(translate_canvas_, rotate_center_x, rotate_center_y); - rotate_center_x -= translate_x_; - rotate_center_y -= translate_y_; - float rotate_offset_x, rotate_offset_y; - RotateOperation::get_rotation_offset( - scale_canvas_, rotate_canvas_, rotate_offset_x, rotate_offset_y); - - for (; !it.is_end(); ++it) { - float x = rotate_offset_x + (it.x - translate_x_); - float y = rotate_offset_y + (it.y - translate_y_); - RotateOperation::rotate_coords( - x, y, rotate_center_x, rotate_center_y, rotate_sine_, rotate_cosine_); - - x = ScaleOperation::scale_coord_inverted(x + scale_offset_x, scale_center_x, scale_); - y = ScaleOperation::scale_coord_inverted(y + scale_offset_y, scale_center_y, scale_); - - input_img->read_elem_sampled(x, y, sampler_, it.out); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TransformOperation.h b/source/blender/compositor/operations/COM_TransformOperation.h deleted file mode 100644 index 0603cc16e5a..00000000000 --- a/source/blender/compositor/operations/COM_TransformOperation.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -class TransformOperation : public MultiThreadedOperation { - private: - constexpr static int IMAGE_INPUT_INDEX = 0; - constexpr static int X_INPUT_INDEX = 1; - constexpr static int Y_INPUT_INDEX = 2; - constexpr static int DEGREE_INPUT_INDEX = 3; - constexpr static int SCALE_INPUT_INDEX = 4; - - float rotate_cosine_; - float rotate_sine_; - int translate_x_; - int translate_y_; - float scale_; - rcti scale_canvas_ = COM_AREA_NONE; - rcti rotate_canvas_ = COM_AREA_NONE; - rcti translate_canvas_ = COM_AREA_NONE; - - /* Set variables. */ - PixelSampler sampler_; - bool convert_degree_to_rad_; - float translate_factor_x_; - float translate_factor_y_; - bool invert_; - - public: - TransformOperation(); - - void set_translate_factor_xy(float x, float y) - { - translate_factor_x_ = x; - translate_factor_y_ = y; - } - - void set_convert_rotate_degree_to_rad(bool value) - { - convert_degree_to_rad_ = value; - } - - void set_sampler(PixelSampler sampler) - { - sampler_ = sampler; - } - - void set_invert(bool value) - { - invert_ = value; - } - - void init_data() override; - 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 inputs) override; - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - private: - /** Translate -> Rotate -> Scale. */ - void transform(BuffersIterator &it, const MemoryBuffer *input_img); - /** Scale -> Rotate -> Translate. */ - void transform_inverted(BuffersIterator &it, const MemoryBuffer *input_img); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cc b/source/blender/compositor/operations/COM_TranslateOperation.cc deleted file mode 100644 index 4917f2b1e8f..00000000000 --- a/source/blender/compositor/operations/COM_TranslateOperation.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_TranslateOperation.h" - -namespace blender::compositor { - -TranslateOperation::TranslateOperation() : TranslateOperation(DataType::Color) {} -TranslateOperation::TranslateOperation(DataType data_type, ResizeMode resize_mode) -{ - this->add_input_socket(data_type, resize_mode); - this->add_input_socket(DataType::Value, ResizeMode::None); - this->add_input_socket(DataType::Value, ResizeMode::None); - this->add_output_socket(data_type); - this->set_canvas_input_index(0); - is_delta_set_ = false; - is_relative_ = false; - this->x_extend_mode_ = MemoryBufferExtend::Clip; - this->y_extend_mode_ = MemoryBufferExtend::Clip; - this->sampler_ = PixelSampler::Nearest; - - this->flags_.can_be_constant = true; -} - -void TranslateOperation::set_wrapping(int wrapping_type) -{ - switch (wrapping_type) { - case CMP_NODE_WRAP_X: - x_extend_mode_ = MemoryBufferExtend::Repeat; - break; - case CMP_NODE_WRAP_Y: - y_extend_mode_ = MemoryBufferExtend::Repeat; - break; - case CMP_NODE_WRAP_XY: - x_extend_mode_ = MemoryBufferExtend::Repeat; - y_extend_mode_ = MemoryBufferExtend::Repeat; - break; - default: - break; - } -} - -void TranslateOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) -{ - ensure_delta(); -} - -void TranslateOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - if (input_idx == 0) { - ensure_delta(); - r_input_area = output_area; - if (x_extend_mode_ == MemoryBufferExtend::Clip) { - const int delta_x = this->get_delta_x(); - BLI_rcti_translate(&r_input_area, -delta_x, 0); - } - else if (x_extend_mode_ == MemoryBufferExtend::Repeat) { - /* The region of interest should consider the whole input image to avoid cropping effects, - * e.g. by prior scaling or rotating. - * NOTE: this is still consistent with immediate realization of transform nodes in GPU - * compositor, where nodes are to be evaluated from left to right. */ - const int in_width = get_width(); - BLI_rcti_resize_x(&r_input_area, in_width); - } - - if (y_extend_mode_ == MemoryBufferExtend::Clip) { - const int delta_y = this->get_delta_y(); - BLI_rcti_translate(&r_input_area, 0, -delta_y); - } - else if (y_extend_mode_ == MemoryBufferExtend::Repeat) { - const int in_height = get_height(); - BLI_rcti_resize_y(&r_input_area, in_height); - } - } - else { - r_input_area = output_area; - } -} - -void TranslateOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input = inputs[0]; - /* Linking X and Y input sockets to non-constant input may result in a non-constant output, see - * Stabilize2dNode for example. */ - if (input->is_a_single_elem() && output->is_a_single_elem()) { - copy_v4_v4(output->get_elem(0, 0), input->get_elem(0, 0)); - return; - } - - /* Some compositor operations produce an empty output buffer by specifying a COM_AREA_NONE canvas - * to indicate an invalid output, for instance, when the Mask operation reference an invalid - * mask. The intention is that this buffer would signal that a fallback value would fill the - * canvas of consumer operations. Since the aforementioned filling is achieved through the - * Translate operation as part of canvas conversion in COM_convert_canvas, we handle the empty - * buffer case here and fill the output using a fallback black color. */ - if (BLI_rcti_is_empty(&input->get_rect())) { - const float value[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - output->fill(area, value); - return; - } - - float delta_x = this->get_delta_x(); - float delta_y = this->get_delta_y(); - if (sampler_ == PixelSampler::Nearest) { - /* Use same rounding convention for GPU compositor. */ - delta_x = round(delta_x); - delta_y = round(delta_y); - } - - for (int y = area.ymin; y < area.ymax; y++) { - float *out = output->get_elem(area.xmin, y); - for (int x = area.xmin; x < area.xmax; x++) { - const float input_x = x - delta_x; - const float input_y = y - delta_y; - input->read(out, input_x, input_y, sampler_, x_extend_mode_, y_extend_mode_); - out += output->elem_stride; - } - } -} - -TranslateCanvasOperation::TranslateCanvasOperation() - : TranslateOperation(DataType::Color, ResizeMode::None) -{ -} - -void TranslateCanvasOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - const bool determined = - get_input_socket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area); - if (determined) { - NodeOperationInput *x_socket = get_input_socket(X_INPUT_INDEX); - NodeOperationInput *y_socket = get_input_socket(Y_INPUT_INDEX); - rcti unused = COM_AREA_NONE; - x_socket->determine_canvas(r_area, unused); - y_socket->determine_canvas(r_area, unused); - - ensure_delta(); - const float delta_x = x_extend_mode_ == MemoryBufferExtend::Clip ? get_delta_x() : 0.0f; - const float delta_y = y_extend_mode_ == MemoryBufferExtend::Clip ? get_delta_y() : 0.0f; - BLI_rcti_translate(&r_area, delta_x, delta_y); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h deleted file mode 100644 index 5300a10026d..00000000000 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ /dev/null @@ -1,107 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_utildefines.h" -#include "COM_ConstantOperation.h" -#include "COM_MultiThreadedOperation.h" - -#include - -namespace blender::compositor { - -class TranslateOperation : public MultiThreadedOperation { - protected: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int X_INPUT_INDEX = 1; - static constexpr int Y_INPUT_INDEX = 2; - - private: - float delta_x_; - float delta_y_; - bool is_delta_set_; - bool is_relative_; - PixelSampler sampler_; - - std::mutex mutex_; - - protected: - MemoryBufferExtend x_extend_mode_; - MemoryBufferExtend y_extend_mode_; - - public: - TranslateOperation(); - TranslateOperation(DataType data_type, ResizeMode mode = ResizeMode::Center); - - float get_delta_x() - { - BLI_assert(is_delta_set_); - return delta_x_; - } - float get_delta_y() - { - BLI_assert(is_delta_set_); - return delta_y_; - } - - void set_is_relative(const bool is_relative) - { - is_relative_ = is_relative; - } - bool get_is_relative() - { - return is_relative_; - } - - PixelSampler get_sampler() - { - return sampler_; - } - void set_sampler(PixelSampler sampler) - { - sampler_ = sampler; - } - - inline void ensure_delta() - { - if (!is_delta_set_) { - std::unique_lock lock(mutex_); - if (is_delta_set_) { - return; - } - - delta_x_ = get_input_operation(X_INPUT_INDEX)->get_constant_value_default(0.0f); - delta_y_ = get_input_operation(Y_INPUT_INDEX)->get_constant_value_default(0.0f); - if (get_is_relative()) { - const int input_width = BLI_rcti_size_x( - &get_input_operation(IMAGE_INPUT_INDEX)->get_canvas()); - const int input_height = BLI_rcti_size_y( - &get_input_operation(IMAGE_INPUT_INDEX)->get_canvas()); - delta_x_ *= input_width; - delta_y_ *= input_height; - } - - is_delta_set_ = true; - } - } - void set_wrapping(int wrapping_type); - - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; - - void update_memory_buffer_started(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class TranslateCanvasOperation : public TranslateOperation { - public: - TranslateCanvasOperation(); - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc deleted file mode 100644 index 90a9732c92a..00000000000 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BLI_math_base.hh" -#include "BLI_math_vector.hh" - -#include "COM_VariableSizeBokehBlurOperation.h" - -namespace blender::compositor { - -VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color, ResizeMode::Align); /* Do not resize the bokeh image. */ - this->add_input_socket(DataType::Value); /* Radius. */ - this->add_input_socket(DataType::Value); /* Bounding Box. */ -#ifdef COM_DEFOCUS_SEARCH - /* Inverse search radius optimization structure. */ - this->add_input_socket(DataType::Color, ResizeMode::None); -#endif - this->add_output_socket(DataType::Color); - flags_.can_be_constant = true; - - max_blur_ = 32.0f; - threshold_ = 1.0f; - do_size_scale_ = false; -} - -struct VariableSizeBokehBlurTileData { - MemoryBuffer *color; - MemoryBuffer *bokeh; - MemoryBuffer *size; - MemoryBuffer *mask; - int max_blur_scalar; -}; - -void VariableSizeBokehBlurOperation::get_area_of_interest(const int input_idx, - const rcti &output_area, - rcti &r_input_area) -{ - switch (input_idx) { - case IMAGE_INPUT_INDEX: - case BOUNDING_BOX_INPUT_INDEX: - case SIZE_INPUT_INDEX: { - const float max_dim = std::max(get_width(), get_height()); - const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; - const int max_blur_scalar = max_blur_ * scalar; - r_input_area.xmax = output_area.xmax + max_blur_scalar + 2; - r_input_area.xmin = output_area.xmin - max_blur_scalar - 2; - r_input_area.ymax = output_area.ymax + max_blur_scalar + 2; - r_input_area.ymin = output_area.ymin - max_blur_scalar - 2; - break; - } - case BOKEH_INPUT_INDEX: { - r_input_area = output_area; - r_input_area.xmax = r_input_area.xmin + COM_BLUR_BOKEH_PIXELS; - r_input_area.ymax = r_input_area.ymin + COM_BLUR_BOKEH_PIXELS; - break; - } -#ifdef COM_DEFOCUS_SEARCH - case DEFOCUS_INPUT_INDEX: { - r_input_area.xmax = (output_area.xmax / InverseSearchRadiusOperation::DIVIDER) + 1; - r_input_area.xmin = (output_area.xmin / InverseSearchRadiusOperation::DIVIDER) - 1; - r_input_area.ymax = (output_area.ymax / InverseSearchRadiusOperation::DIVIDER) + 1; - r_input_area.ymin = (output_area.ymin / InverseSearchRadiusOperation::DIVIDER) - 1; - break; - } -#endif - } -} - -void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - MemoryBuffer *input_buffer = inputs[0]; - MemoryBuffer *bokeh_buffer = inputs[1]; - MemoryBuffer *size_buffer = inputs[2]; - MemoryBuffer *mask_buffer = inputs[3]; - - const float max_dim = std::max(get_width(), get_height()); - const float base_size = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; - const float maximum_size = size_buffer->get_max_value(); - const int search_radius = math::clamp(int(maximum_size * base_size), 0, max_blur_); - - BuffersIterator it = output->iterate_with({}, area); - for (; !it.is_end(); ++it) { - if (*mask_buffer->get_elem(it.x, it.y) <= 0.0f) { - copy_v4_v4(it.out, input_buffer->get_elem(it.x, it.y)); - continue; - } - - const float center_size = math::max(0.0f, *size_buffer->get_elem(it.x, it.y) * base_size); - - float4 accumulated_color = float4(input_buffer->get_elem(it.x, it.y)); - float4 accumulated_weight = float4(1.0f); - if (center_size >= threshold_) { - for (int yi = -search_radius; yi <= search_radius; ++yi) { - for (int xi = -search_radius; xi <= search_radius; ++xi) { - if (xi == 0 && yi == 0) { - continue; - } - const float candidate_size = math::max( - 0.0f, *size_buffer->get_elem_clamped(it.x + xi, it.y + yi) * base_size); - const float size = math::min(center_size, candidate_size); - if (size < threshold_ || math::max(math::abs(xi), math::abs(yi)) > size) { - continue; - } - - const float2 normalized_texel = (float2(xi, yi) + size + 0.5f) / (size * 2.0f + 1.0f); - const float2 weight_texel = 1.0f - normalized_texel; - const float4 weight = bokeh_buffer->texture_bilinear_extend(weight_texel); - const float4 color = input_buffer->get_elem_clamped(it.x + xi, it.y + yi); - accumulated_color += color * weight; - accumulated_weight += weight; - } - } - } - - const float4 final_color = math::safe_divide(accumulated_color, accumulated_weight); - copy_v4_v4(it.out, final_color); - - /* blend in out values over the threshold, otherwise we get sharp, ugly transitions */ - if ((center_size > threshold_) && (center_size < threshold_ * 2.0f)) { - /* factor from 0-1 */ - float fac = (center_size - threshold_) / threshold_; - interp_v4_v4v4(it.out, input_buffer->get_elem(it.x, it.y), it.out, fac); - } - } -} - -#ifdef COM_DEFOCUS_SEARCH -/* #InverseSearchRadiusOperation. */ -InverseSearchRadiusOperation::InverseSearchRadiusOperation() -{ - this->add_input_socket(DataType::Value, ResizeMode::Align); /* Radius. */ - this->add_output_socket(DataType::Color); -} - -void InverseSearchRadiusOperation::determine_resolution(uint resolution[2], - uint preferred_resolution[2]) -{ - NodeOperation::determine_resolution(resolution, preferred_resolution); - resolution[0] = resolution[0] / DIVIDER; - resolution[1] = resolution[1] / DIVIDER; -} - -#endif - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h deleted file mode 100644 index 3654c66ef04..00000000000 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MultiThreadedOperation.h" - -namespace blender::compositor { - -// #define COM_DEFOCUS_SEARCH - -class VariableSizeBokehBlurOperation : public MultiThreadedOperation { - private: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int BOKEH_INPUT_INDEX = 1; - static constexpr int SIZE_INPUT_INDEX = 2; - static constexpr int BOUNDING_BOX_INPUT_INDEX = 3; -#ifdef COM_DEFOCUS_SEARCH - static constexpr int DEFOCUS_INPUT_INDEX = 4; -#endif - - int max_blur_; - float threshold_; - bool do_size_scale_; /* scale size, matching 'BokehBlurNode' */ - - public: - VariableSizeBokehBlurOperation(); - - void set_max_blur(int max_radius) - { - max_blur_ = max_radius; - } - - void set_threshold(float threshold) - { - threshold_ = threshold; - } - - void set_do_scale_size(bool scale_size) - { - do_size_scale_ = scale_size; - } - - 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 inputs) override; -}; - -/* Currently unused. If ever used, it needs full-frame implementation. */ -#ifdef COM_DEFOCUS_SEARCH -class InverseSearchRadiusOperation : public NodeOperation { - private: - int max_blur_; - - public: - static const int DIVIDER = 4; - - InverseSearchRadiusOperation(); - - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - - void set_max_blur(int max_radius) - { - max_blur_ = max_radius; - } -}; -#endif - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc deleted file mode 100644 index 074c9a0bfd2..00000000000 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc +++ /dev/null @@ -1,502 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#include "BLI_array.hh" -#include "BLI_index_range.hh" -#include "BLI_math_base.hh" -#include "BLI_math_vector.h" -#include "BLI_math_vector.hh" -#include "BLI_task.hh" - -#include "COM_VectorBlurOperation.h" - -/* This is identical to the compositor implementation in compositor_motion_blur_info.hh and its - * related files with the necessary adjustments to make it work for the CPU. */ - -#define MOTION_BLUR_TILE_SIZE 32 -#define DEPTH_SCALE 100.0f - -namespace blender::compositor { - -VectorBlurOperation::VectorBlurOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); - settings_ = nullptr; -} - -/* Returns the input velocity that has the larger magnitude. */ -static float2 max_velocity(const float2 &a, const float2 &b) -{ - return math::length_squared(a) > math::length_squared(b) ? a : b; -} - -/* Identical to motion_blur_tile_indirection_pack_payload, encodes the value and its texel such - * that the integer length of the value is encoded in the most significant bits, then the x value - * of the texel are encoded in the middle bits, then the y value of the texel is stored in the - * least significant bits. */ -static uint32_t velocity_atomic_max_value(const float2 &value, const int2 &texel) -{ - const uint32_t length_bits = math::min(uint32_t(math::ceil(math::length(value))), 0x3FFFu); - return (length_bits << 18u) | ((texel.x & 0x1FFu) << 9u) | (texel.y & 0x1FFu); -} - -/* Returns the input velocity that has the larger integer magnitude, and if equal the larger x - * texel coordinates, and if equal, the larger y texel coordinates. It might be weird that we use - * an approximate comparison, but this is used for compatibility with the GPU code, which uses - * atomic integer operations, hence the limited precision. See velocity_atomic_max_value for more - * information. */ -static float2 max_velocity_approximate(const float2 &a, - const float2 &b, - const int2 &a_texel, - const int2 &b_texel) -{ - return velocity_atomic_max_value(a, a_texel) > velocity_atomic_max_value(b, b_texel) ? a : b; -} - -/* Reduces each 32x32 block of velocity pixels into a single velocity whose magnitude is largest. - * Each of the previous and next velocities are reduces independently. */ -static MemoryBuffer compute_max_tile_velocity(MemoryBuffer *velocity_buffer) -{ - const int2 tile_size = int2(MOTION_BLUR_TILE_SIZE); - const int2 velocity_size = int2(velocity_buffer->get_width(), velocity_buffer->get_height()); - const int2 tiles_count = math::divide_ceil(velocity_size, tile_size); - MemoryBuffer output(DataType::Color, tiles_count.x, tiles_count.y); - - threading::parallel_for(IndexRange(tiles_count.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(tiles_count.x)) { - const int2 texel = int2(x, y); - - float2 max_previous_velocity = float2(0.0f); - float2 max_next_velocity = float2(0.0f); - - for (int j = 0; j < tile_size.y; j++) { - for (int i = 0; i < tile_size.x; i++) { - int2 sub_texel = texel * tile_size + int2(i, j); - const float4 velocity = velocity_buffer->get_elem_clamped(sub_texel.x, sub_texel.y); - max_previous_velocity = max_velocity(velocity.xy(), max_previous_velocity); - max_next_velocity = max_velocity(velocity.zw(), max_next_velocity); - } - } - - const float4 max_velocity = float4(max_previous_velocity, max_next_velocity); - copy_v4_v4(output.get_elem(texel.x, texel.y), max_velocity); - } - } - }); - - return output; -} - -struct MotionRect { - int2 bottom_left; - int2 extent; -}; - -static MotionRect compute_motion_rect(int2 tile, float2 motion, int2 size) -{ - /* `ceil()` to number of tile touched. */ - int2 point1 = tile + int2(math::sign(motion) * - math::ceil(math::abs(motion) / float(MOTION_BLUR_TILE_SIZE))); - int2 point2 = tile; - - int2 max_point = math::max(point1, point2); - int2 min_point = math::min(point1, point2); - /* Clamp to bounds. */ - max_point = math::min(max_point, size - 1); - min_point = math::max(min_point, int2(0)); - - MotionRect rect; - rect.bottom_left = min_point; - rect.extent = 1 + max_point - min_point; - return rect; -} - -struct MotionLine { - /** Origin of the line. */ - float2 origin; - /** Normal to the line direction. */ - float2 normal; -}; - -static MotionLine compute_motion_line(int2 tile, float2 motion) -{ - float magnitude = math::length(motion); - float2 dir = magnitude != 0.0f ? motion / magnitude : motion; - - MotionLine line; - line.origin = float2(tile); - /* Rotate 90 degrees counter-clockwise. */ - line.normal = float2(-dir.y, dir.x); - return line; -} - -static bool is_inside_motion_line(int2 tile, MotionLine motion_line) -{ - /* NOTE: Everything in is tile unit. */ - float distance_to_line = math::dot(motion_line.normal, motion_line.origin - float2(tile)); - /* In order to be conservative and for simplicity, we use the tiles bounding circles. - * Consider that both the tile and the line have bounding radius of M_SQRT1_2. */ - return math::abs(distance_to_line) < math::numbers::sqrt2_v; -} - -/* The max tile velocity image computes the maximum within 32x32 blocks, while the velocity can - * in fact extend beyond such a small block. So we dilate the max blocks by taking the maximum - * along the path of each of the max velocity tiles. Since the shader uses custom max atomics, - * the output will be an indirection buffer that points to a particular tile in the original max - * tile velocity image. This is done as a form of performance optimization, see the shader for - * more information. */ -static MemoryBuffer dilate_max_velocity(MemoryBuffer &max_tile_velocity, float shutter_speed) -{ - const int2 size = int2(max_tile_velocity.get_width(), max_tile_velocity.get_height()); - MemoryBuffer output(DataType::Color, size.x, size.y); - const float4 zero_value = float4(0.0f); - output.fill(output.get_rect(), zero_value); - - for (const int64_t y : IndexRange(size.y)) { - for (const int64_t x : IndexRange(size.x)) { - const int2 src_tile = int2(x, y); - - float4 max_motion = float4(max_tile_velocity.get_elem(x, y)) * - float4(float2(shutter_speed), float2(-shutter_speed)); - - { - /* Rectangular area (in tiles) where the motion vector spreads. */ - MotionRect motion_rect = compute_motion_rect(src_tile, max_motion.xy(), size); - MotionLine motion_line = compute_motion_line(src_tile, max_motion.xy()); - /* Do a conservative rasterization of the line of the motion vector line. */ - for (int j = 0; j < motion_rect.extent.y; j++) { - for (int i = 0; i < motion_rect.extent.x; i++) { - int2 tile = motion_rect.bottom_left + int2(i, j); - if (is_inside_motion_line(tile, motion_line)) { - float *pixel = output.get_elem(tile.x, tile.y); - copy_v2_v2(pixel + 2, - max_velocity_approximate(pixel + 2, max_motion.zw(), tile, src_tile)); - copy_v2_v2(pixel, max_velocity_approximate(pixel, max_motion.xy(), tile, src_tile)); - } - } - } - } - - { - /* Rectangular area (in tiles) where the motion vector spreads. */ - MotionRect motion_rect = compute_motion_rect(src_tile, max_motion.zw(), size); - MotionLine motion_line = compute_motion_line(src_tile, max_motion.zw()); - /* Do a conservative rasterization of the line of the motion vector line. */ - for (int j = 0; j < motion_rect.extent.y; j++) { - for (int i = 0; i < motion_rect.extent.x; i++) { - int2 tile = motion_rect.bottom_left + int2(i, j); - if (is_inside_motion_line(tile, motion_line)) { - float *pixel = output.get_elem(tile.x, tile.y); - copy_v2_v2(pixel, max_velocity_approximate(pixel, max_motion.xy(), tile, src_tile)); - copy_v2_v2(pixel + 2, - max_velocity_approximate(pixel + 2, max_motion.zw(), tile, src_tile)); - } - } - } - } - } - } - - return output; -} - -/* Interleaved gradient noise by Jorge Jimenez - * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare. */ -static float interleaved_gradient_noise(int2 p) -{ - return math::fract(52.9829189f * math::fract(0.06711056f * p.x + 0.00583715f * p.y)); -} - -static float2 spread_compare(float center_motion_length, - float sample_motion_length, - float offset_length) -{ - return math::clamp( - float2(center_motion_length, sample_motion_length) - offset_length + 1.0f, 0.0f, 1.0f); -} - -static float2 depth_compare(float center_depth, float sample_depth) -{ - float2 depth_scale = float2(DEPTH_SCALE, -DEPTH_SCALE); - return math::clamp(0.5f + depth_scale * (sample_depth - center_depth), 0.0f, 1.0f); -} - -/* Kill contribution if not going the same direction. */ -static float dir_compare(float2 offset, float2 sample_motion, float sample_motion_length) -{ - if (sample_motion_length < 0.5f) { - return 1.0f; - } - return (math::dot(offset, sample_motion) > 0.0f) ? 1.0f : 0.0f; -} - -/* Return background (x) and foreground (y) weights. */ -static float2 sample_weights(float center_depth, - float sample_depth, - float center_motion_length, - float sample_motion_length, - float offset_length) -{ - /* Classify foreground/background. */ - float2 depth_weight = depth_compare(center_depth, sample_depth); - /* Weight if sample is overlapping or under the center pixel. */ - float2 spread_weight = spread_compare(center_motion_length, sample_motion_length, offset_length); - return depth_weight * spread_weight; -} - -struct Accumulator { - float4 fg; - float4 bg; - /** x: Background, y: Foreground, z: dir. */ - float3 weight; -}; - -static void gather_sample(MemoryBuffer *image_buffer, - MemoryBuffer *depth_buffer, - MemoryBuffer *velocity_buffer, - int2 size, - float2 screen_uv, - float center_depth, - float center_motion_len, - float2 offset, - float offset_len, - const bool next, - float shutter_speed, - Accumulator &accum) -{ - float2 sample_uv = screen_uv - offset / float2(size); - float4 sample_vectors = velocity_buffer->texture_bilinear_extend(sample_uv) * - float4(float2(shutter_speed), float2(-shutter_speed)); - float2 sample_motion = (next) ? sample_vectors.zw() : sample_vectors.xy(); - float sample_motion_len = math::length(sample_motion); - float sample_depth = depth_buffer->texture_bilinear_extend(sample_uv).x; - float4 sample_color = image_buffer->texture_bilinear_extend(sample_uv); - - float2 direct_weights = sample_weights( - center_depth, sample_depth, center_motion_len, sample_motion_len, offset_len); - - float3 weights; - weights.x = direct_weights.x; - weights.y = direct_weights.y; - weights.z = dir_compare(offset, sample_motion, sample_motion_len); - weights.x *= weights.z; - weights.y *= weights.z; - - accum.fg += sample_color * weights.y; - accum.bg += sample_color * weights.x; - accum.weight += weights; -} - -static void gather_blur(MemoryBuffer *image_buffer, - MemoryBuffer *depth_buffer, - MemoryBuffer *velocity_buffer, - int2 size, - float2 screen_uv, - float2 center_motion, - float center_depth, - float2 max_motion, - float ofs, - const bool next, - int samples_count, - float shutter_speed, - Accumulator &accum) -{ - float center_motion_len = math::length(center_motion); - float max_motion_len = math::length(max_motion); - - /* Tile boundaries randomization can fetch a tile where there is less motion than this pixel. - * Fix this by overriding the max_motion. */ - if (max_motion_len < center_motion_len) { - max_motion_len = center_motion_len; - max_motion = center_motion; - } - - if (max_motion_len < 0.5f) { - return; - } - - int i; - float t, inc = 1.0f / float(samples_count); - for (i = 0, t = ofs * inc; i < samples_count; i++, t += inc) { - gather_sample(image_buffer, - depth_buffer, - velocity_buffer, - size, - screen_uv, - center_depth, - center_motion_len, - max_motion * t, - max_motion_len * t, - next, - shutter_speed, - accum); - } - - if (center_motion_len < 0.5f) { - return; - } - - for (i = 0, t = ofs * inc; i < samples_count; i++, t += inc) { - /* Also sample in center motion direction. - * Allow recovering motion where there is conflicting - * motion between foreground and background. */ - gather_sample(image_buffer, - depth_buffer, - velocity_buffer, - size, - screen_uv, - center_depth, - center_motion_len, - center_motion * t, - center_motion_len * t, - next, - shutter_speed, - accum); - } -} - -static void motion_blur(MemoryBuffer *image_buffer, - MemoryBuffer *depth_buffer, - MemoryBuffer *velocity_buffer, - MemoryBuffer *max_velocity_buffer, - MemoryBuffer *output, - int samples_count, - float shutter_speed) -{ - const int2 size = int2(image_buffer->get_width(), image_buffer->get_height()); - threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) { - for (const int64_t y : sub_y_range) { - for (const int64_t x : IndexRange(size.x)) { - const int2 texel = int2(x, y); - float2 uv = (float2(texel) + 0.5f) / float2(size); - - /* Data of the center pixel of the gather (target). */ - float center_depth = *depth_buffer->get_elem(x, y); - float4 center_motion = float4(velocity_buffer->get_elem(x, y)) * - float4(float2(shutter_speed), float2(-shutter_speed)); - float4 center_color = image_buffer->get_elem(x, y); - - /* Randomize tile boundary to avoid ugly discontinuities. Randomize 1/4th of the tile. - * Note this randomize only in one direction but in practice it's enough. */ - float rand = interleaved_gradient_noise(texel); - int2 tile = (texel + int2(rand * 2.0f - 1.0f * float(MOTION_BLUR_TILE_SIZE) * 0.25f)) / - MOTION_BLUR_TILE_SIZE; - - /* No need to multiply by the shutter speed and invert the next velocities since this was - * already done in dilate_max_velocity. */ - float4 max_motion = max_velocity_buffer->get_elem(tile.x, tile.y); - - Accumulator accum; - accum.weight = float3(0.0f, 0.0f, 1.0f); - accum.bg = float4(0.0f); - accum.fg = float4(0.0f); - /* First linear gather. time = [T - delta, T] */ - gather_blur(image_buffer, - depth_buffer, - velocity_buffer, - size, - uv, - center_motion.xy(), - center_depth, - max_motion.xy(), - rand, - false, - samples_count, - shutter_speed, - accum); - /* Second linear gather. time = [T, T + delta] */ - gather_blur(image_buffer, - depth_buffer, - velocity_buffer, - size, - uv, - center_motion.zw(), - center_depth, - max_motion.zw(), - rand, - true, - samples_count, - shutter_speed, - accum); - -#if 1 /* Own addition. Not present in reference implementation. */ - /* Avoid division by 0.0. */ - float w = 1.0f / (50.0f * float(samples_count) * 4.0f); - accum.bg += center_color * w; - accum.weight.x += w; - /* NOTE: In Jimenez's presentation, they used center sample. - * We use background color as it contains more information for foreground - * elements that have not enough weights. - * Yield better blur in complex motion. */ - center_color = accum.bg / accum.weight.x; -#endif - /* Merge background. */ - accum.fg += accum.bg; - accum.weight.y += accum.weight.x; - /* Balance accumulation for failed samples. - * We replace the missing foreground by the background. */ - float blend_fac = math::clamp(1.0f - accum.weight.y / accum.weight.z, 0.0f, 1.0f); - float4 out_color = (accum.fg / accum.weight.z) + center_color * blend_fac; - - copy_v4_v4(output->get_elem(x, y), out_color); - } - } - }); -} - -void VectorBlurOperation::update_memory_buffer(MemoryBuffer *output, - const rcti & /*area*/, - Span inputs) -{ - MemoryBuffer *image = inputs[IMAGE_INPUT_INDEX]; - MemoryBuffer *depth = inputs[DEPTH_INPUT_INDEX]; - MemoryBuffer *velocity = inputs[VELOCITY_INPUT_INDEX]; - - const bool image_needs_inflation = image->is_a_single_elem(); - const bool depth_needs_inflation = depth->is_a_single_elem(); - const bool velocity_needs_inflation = velocity->is_a_single_elem(); - - MemoryBuffer *image_buffer = image_needs_inflation ? image->inflate() : image; - MemoryBuffer *depth_buffer = depth_needs_inflation ? depth->inflate() : depth; - MemoryBuffer *velocity_buffer = velocity_needs_inflation ? velocity->inflate() : velocity; - - MemoryBuffer max_tile_velocity = compute_max_tile_velocity(velocity_buffer); - MemoryBuffer max_velocity = dilate_max_velocity(max_tile_velocity, settings_->fac); - motion_blur(image_buffer, - depth_buffer, - velocity_buffer, - &max_velocity, - output, - settings_->samples, - settings_->fac); - - if (image_needs_inflation) { - delete image_buffer; - } - - if (depth_needs_inflation) { - delete depth_buffer; - } - - if (velocity_needs_inflation) { - delete velocity_buffer; - } -} - -void VectorBlurOperation::get_area_of_interest(const int /*input_idx*/, - const rcti & /*output_area*/, - rcti &r_input_area) -{ - r_input_area = this->get_canvas(); -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h deleted file mode 100644 index 66149cd0b49..00000000000 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-FileCopyrightText: 2024 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_NodeOperation.h" -#include "DNA_node_types.h" - -namespace blender::compositor { - -class VectorBlurOperation : public NodeOperation { - private: - static constexpr int IMAGE_INPUT_INDEX = 0; - static constexpr int DEPTH_INPUT_INDEX = 1; - static constexpr int VELOCITY_INPUT_INDEX = 2; - - const NodeBlurData *settings_; - - public: - VectorBlurOperation(); - - void set_vector_blur_settings(const NodeBlurData *settings) - { - settings_ = settings; - } - - void update_memory_buffer(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cc b/source/blender/compositor/operations/COM_VectorCurveOperation.cc deleted file mode 100644 index a293d958237..00000000000 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_VectorCurveOperation.h" - -#include "BKE_colortools.hh" - -namespace blender::compositor { - -VectorCurveOperation::VectorCurveOperation() -{ - this->add_input_socket(DataType::Vector); - this->add_output_socket(DataType::Vector); - - this->flags_.can_be_constant = true; -} - -void VectorCurveOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - CurveMapping *curve_map = curve_mapping_; - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - BKE_curvemapping_evaluate_premulRGBF(curve_map, it.out, it.in(0)); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h deleted file mode 100644 index ee5413abf7b..00000000000 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_CurveBaseOperation.h" - -namespace blender::compositor { - -class VectorCurveOperation : public CurveBaseOperation { - public: - VectorCurveOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc deleted file mode 100644 index 5f30c28fb9f..00000000000 --- a/source/blender/compositor/operations/COM_ViewerOperation.cc +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ViewerOperation.h" -#include "BKE_image.hh" -#include "BKE_scene.hh" -#include "COM_ExecutionSystem.h" - -#include "IMB_colormanagement.hh" -#include "IMB_imbuf.hh" -#include "IMB_imbuf_types.hh" - -namespace blender::compositor { - -ViewerOperation::ViewerOperation() -{ - this->set_image(nullptr); - this->set_image_user(nullptr); - output_buffer_ = nullptr; - active_ = false; - view_settings_ = nullptr; - display_settings_ = nullptr; - use_alpha_input_ = false; - - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - - rd_ = nullptr; - view_name_ = nullptr; - flags_.use_viewer_border = true; - flags_.is_viewer_operation = true; -} - -void ViewerOperation::init_execution() -{ - if (is_active_viewer_output() && !exec_system_->is_breaked()) { - init_image(); - } -} - -void ViewerOperation::deinit_execution() -{ - output_buffer_ = nullptr; -} - -void ViewerOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) -{ - int scene_render_width, scene_render_height; - BKE_render_resolution(rd_, false, &scene_render_width, &scene_render_height); - - rcti local_preferred = preferred_area; - local_preferred.xmax = local_preferred.xmin + scene_render_width; - local_preferred.ymax = local_preferred.ymin + scene_render_height; - - NodeOperation::determine_canvas(local_preferred, r_area); -} - -void ViewerOperation::init_image() -{ - Image *ima = image_; - ImageUser iuser = *image_user_; - void *lock; - ImBuf *ibuf; - - /* make sure the image has the correct number of views */ - if (ima && BKE_scene_multiview_is_render_view_first(rd_, view_name_)) { - BKE_image_ensure_viewer_views(rd_, ima, image_user_); - } - - BLI_thread_lock(LOCK_DRAW_IMAGE); - - /* local changes to the original ImageUser */ - iuser.multi_index = BKE_scene_multiview_view_id_get(rd_, view_name_); - ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); - - if (!ibuf) { - BLI_thread_unlock(LOCK_DRAW_IMAGE); - return; - } - - if (ibuf->x != get_width() || ibuf->y != get_height()) { - - imb_freerectImBuf(ibuf); - imb_freerectfloatImBuf(ibuf); - ibuf->x = get_width(); - ibuf->y = get_height(); - /* zero size can happen if no image buffers exist to define a sensible resolution */ - if (ibuf->x > 0 && ibuf->y > 0) { - imb_addrectfloatImBuf(ibuf, 4); - } - - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - } - - /* now we combine the input with ibuf */ - output_buffer_ = ibuf->float_buffer.data; - - /* needed for display buffer update */ - ibuf_ = ibuf; - - BKE_image_release_ibuf(image_, ibuf_, lock); - - BLI_thread_unlock(LOCK_DRAW_IMAGE); -} - -void ViewerOperation::update_image(const rcti *rect) -{ - if (exec_system_->is_breaked()) { - return; - } - - image_->runtime.backdrop_offset[0] = canvas_.xmin; - image_->runtime.backdrop_offset[1] = canvas_.ymin; - float *buffer = output_buffer_; - IMB_partial_display_buffer_update(ibuf_, - buffer, - nullptr, - get_width(), - 0, - 0, - view_settings_, - display_settings_, - rect->xmin, - rect->ymin, - rect->xmax, - rect->ymax); - - /* This could be improved to use partial updates. For now disabled as the full frame compositor - * would not use partial frames anymore and the image engine requires more testing. */ - BKE_image_partial_update_mark_full_update(image_); - this->update_draw(); -} - -eCompositorPriority ViewerOperation::get_render_priority() const -{ - if (this->is_active_viewer_output()) { - return eCompositorPriority::High; - } - - return eCompositorPriority::Low; -} - -void ViewerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, - const rcti &area, - Span inputs) -{ - if (!output_buffer_) { - return; - } - - MemoryBuffer output_buffer( - output_buffer_, COM_DATA_TYPE_COLOR_CHANNELS, get_width(), get_height()); - const MemoryBuffer *input_image = inputs[0]; - output_buffer.copy_from(input_image, area); - if (use_alpha_input_) { - const MemoryBuffer *input_alpha = inputs[1]; - output_buffer.copy_from(input_alpha, area, 0, COM_DATA_TYPE_VALUE_CHANNELS, 3); - } - - update_image(&area); -} - -void ViewerOperation::update_memory_buffer_finished(MemoryBuffer * /*output*/, - const rcti & /*area*/, - Span /*inputs*/) -{ - if (!image_) { - return; - } - - const std::unique_ptr meta_data = - this->get_input_socket(0)->get_reader()->get_meta_data(); - - if (meta_data && meta_data->is_data) { - image_->flag &= ~IMA_VIEW_AS_RENDER; - /* TODO: Assign image buffer's color space to either non-color or linear, to be fully correct - * about the content of the pixels. This needs to happen consistently with the GPU compositor, - * and also consistently with the ibuf_ acquired as a state of this operation (which is not - * always guaranteed to happen here. */ - } - else { - image_->flag |= IMA_VIEW_AS_RENDER; - } -} - -void ViewerOperation::clear_display_buffer() -{ - BLI_assert(is_active_viewer_output()); - if (exec_system_->is_breaked()) { - return; - } - - init_image(); - if (output_buffer_ == nullptr) { - return; - } - - size_t buf_bytes = size_t(ibuf_->y) * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float); - if (buf_bytes > 0) { - memset(output_buffer_, 0, buf_bytes); - rcti display_area; - BLI_rcti_init(&display_area, 0, ibuf_->x, 0, ibuf_->y); - update_image(&display_area); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h deleted file mode 100644 index 70ddfac6a74..00000000000 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BKE_global.hh" -#include "BLI_rect.h" -#include "COM_MultiThreadedOperation.h" -#include "DNA_image_types.h" - -namespace blender::compositor { - -class ViewerOperation : public MultiThreadedOperation { - private: - /* TODO(manzanilla): To be removed together with tiled implementation. */ - float *output_buffer_; - - Image *image_; - ImageUser *image_user_; - bool active_; - ImBuf *ibuf_; - bool use_alpha_input_; - const RenderData *rd_; - const char *view_name_; - - const ColorManagedViewSettings *view_settings_; - const ColorManagedDisplaySettings *display_settings_; - - public: - ViewerOperation(); - void init_execution() override; - void deinit_execution() override; - void determine_canvas(const rcti &preferred_area, rcti &r_area) override; - bool is_output_operation(bool /*rendering*/) const override - { - if (G.background) { - return false; - } - return is_active_viewer_output(); - } - void set_image(Image *image) - { - image_ = image; - } - void set_image_user(ImageUser *image_user) - { - image_user_ = image_user; - } - bool is_active_viewer_output() const override - { - return active_; - } - void set_active(bool active) - { - active_ = active; - } - eCompositorPriority get_render_priority() const override; - void set_use_alpha_input(bool value) - { - use_alpha_input_ = value; - } - void set_render_data(const RenderData *rd) - { - rd_ = rd; - } - void set_view_name(const char *view_name) - { - view_name_ = view_name; - } - - void set_view_settings(const ColorManagedViewSettings *view_settings) - { - view_settings_ = view_settings; - } - void set_display_settings(const ColorManagedDisplaySettings *display_settings) - { - display_settings_ = display_settings; - } - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - void update_memory_buffer_finished(MemoryBuffer *output, - const rcti &area, - Span inputs) override; - - void clear_display_buffer(); - - private: - void update_image(const rcti *rect); - void init_image(); -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cc b/source/blender/compositor/operations/COM_ZCombineOperation.cc deleted file mode 100644 index cfaf4f1672a..00000000000 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "COM_ZCombineOperation.h" - -namespace blender::compositor { - -ZCombineOperation::ZCombineOperation() -{ - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Value); - this->add_output_socket(DataType::Color); - - flags_.can_be_constant = true; -} - -void ZCombineOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float depth1 = *it.in(1); - const float depth2 = *it.in(3); - const float *color = (depth1 < depth2) ? it.in(0) : it.in(2); - copy_v4_v4(it.out, color); - } -} - -void ZCombineAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float depth1 = *it.in(1); - const float depth2 = *it.in(3); - const float *color1; - const float *color2; - if (depth1 < depth2) { - color1 = it.in(0); - color2 = it.in(2); - } - else { - color1 = it.in(2); - color2 = it.in(0); - } - const float fac = color1[3]; - const float ifac = 1.0f - fac; - it.out[0] = fac * color1[0] + ifac * color2[0]; - it.out[1] = fac * color1[1] + ifac * color2[1]; - it.out[2] = fac * color1[2] + ifac * color2[2]; - it.out[3] = std::max(color1[3], color2[3]); - } -} - -// MASK combine -ZCombineMaskOperation::ZCombineMaskOperation() -{ - this->add_input_socket(DataType::Value); // mask - this->add_input_socket(DataType::Color); - this->add_input_socket(DataType::Color); - this->add_output_socket(DataType::Color); -} - -void ZCombineMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float mask = *it.in(0); - const float *color1 = it.in(1); - const float *color2 = it.in(2); - interp_v4_v4v4(it.out, color1, color2, 1.0f - mask); - } -} - -void ZCombineMaskAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) -{ - for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const float mask = *it.in(0); - const float *color1 = it.in(1); - const float *color2 = it.in(2); - const float fac = (1.0f - mask) * (1.0f - color1[3]) + mask * color2[3]; - const float mfac = 1.0f - fac; - - it.out[0] = color1[0] * mfac + color2[0] * fac; - it.out[1] = color1[1] * mfac + color2[1] * fac; - it.out[2] = color1[2] * mfac + color2[2] * fac; - it.out[3] = std::max(color1[3], color2[3]); - } -} - -} // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h deleted file mode 100644 index efe0b2a2075..00000000000 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-FileCopyrightText: 2011 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "COM_MixOperation.h" - -namespace blender::compositor { - -/** - * this program converts an input color to an output value. - * it assumes we are in sRGB color space. - */ -class ZCombineOperation : public MultiThreadedOperation { - public: - ZCombineOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class ZCombineAlphaOperation : public ZCombineOperation { - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -class ZCombineMaskOperation : public MultiThreadedOperation { - public: - ZCombineMaskOperation(); - - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; -class ZCombineMaskAlphaOperation : public ZCombineMaskOperation { - void update_memory_buffer_partial(MemoryBuffer *output, - const rcti &area, - Span inputs) override; -}; - -} // namespace blender::compositor diff --git a/source/blender/compositor/tests/COM_BufferArea_test.cc b/source/blender/compositor/tests/COM_BufferArea_test.cc deleted file mode 100644 index 4b3024511f6..00000000000 --- a/source/blender/compositor/tests/COM_BufferArea_test.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "testing/testing.h" - -#include "COM_BufferArea.h" - -namespace blender::compositor::tests { - -static rcti create_rect(int width, int height) -{ - rcti rect; - BLI_rcti_init(&rect, 0, width, 0, height); - return rect; -} - -static rcti create_rect(int width, int height, int offset) -{ - rcti rect; - BLI_rcti_init(&rect, offset, offset + width, offset, offset + height); - return rect; -} - -TEST(BufferArea, BufferConstructor) -{ - const int width = 2; - const int height = 3; - BufferArea area(nullptr, width, height, 4); - EXPECT_EQ(area.width(), width); - EXPECT_EQ(area.height(), height); - rcti rect = create_rect(width, height); - EXPECT_TRUE(BLI_rcti_compare(&area.get_rect(), &rect)); -} - -TEST(BufferArea, AreaConstructor) -{ - const int buf_width = 5; - const int area_width = 1; - const int area_height = 3; - rcti area_rect = create_rect(area_width, area_height, 1); - BufferArea area(nullptr, buf_width, area_rect, 4); - EXPECT_EQ(area.width(), area_width); - EXPECT_EQ(area.height(), area_height); - EXPECT_TRUE(BLI_rcti_compare(&area.get_rect(), &area_rect)); -} - -static void fill_buffer_with_indexes(float *buf, int buf_len) -{ - for (int i = 0; i < buf_len; i++) { - buf[i] = i; - } -} - -static void test_single_elem_iteration(float *buffer, BufferArea area) -{ - int elems_count = 0; - for (float *elem : area) { - EXPECT_EQ(elem, buffer); - elems_count++; - } - EXPECT_EQ(elems_count, 1); -} - -static void test_full_buffer_iteration( - float *buf, int buf_width, int buf_len, int num_channels, BufferArea area) -{ - fill_buffer_with_indexes(buf, buf_len); - rcti rect = area.get_rect(); - int x = rect.xmin; - int y = rect.ymin; - for (float *elem : area) { - for (int ch = 0; ch < num_channels; ch++) { - const int buf_index = y * buf_width * num_channels + x * num_channels + ch; - EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON); - } - x++; - if (x == rect.xmax) { - y++; - x = rect.xmin; - } - } - EXPECT_EQ(x, rect.xmin); - EXPECT_EQ(y, rect.ymax); -} - -TEST(BufferArea, SingleElemBufferIteration) -{ - const int buf_width = 4; - const int buf_height = 5; - const int area_width = 2; - const int area_height = 3; - const int num_channels = 4; - const int stride = 0; - float buf[num_channels]; - { - BufferArea area(buf, buf_width, buf_height, stride); - test_single_elem_iteration(buf, area); - } - { - rcti area_rect = create_rect(area_width, area_height, 1); - BufferArea area(buf, buf_width, area_rect, stride); - test_single_elem_iteration(buf, area); - } -} - -TEST(BufferArea, FullBufferIteration) -{ - const int buf_width = 4; - const int area_width = 2; - const int area_height = 3; - const int buf_height = (area_height + 1); - const int num_channels = 4; - const int buf_len = buf_height * buf_width * num_channels; - float buf[buf_len]; - { - BufferArea area(buf, buf_width, buf_height, num_channels); - test_full_buffer_iteration(buf, buf_width, buf_len, num_channels, area); - } - { - rcti area_rect = create_rect(area_width, area_height, 1); - BufferArea area(buf, buf_width, area_rect, num_channels); - test_full_buffer_iteration(buf, buf_width, buf_len, num_channels, area); - } -} - -} // namespace blender::compositor::tests diff --git a/source/blender/compositor/tests/COM_BufferRange_test.cc b/source/blender/compositor/tests/COM_BufferRange_test.cc deleted file mode 100644 index a2cfa3116fd..00000000000 --- a/source/blender/compositor/tests/COM_BufferRange_test.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "testing/testing.h" - -#include "COM_BufferRange.h" - -namespace blender::compositor::tests { - -TEST(BufferRange, Constructor) -{ - const int size = 5; - BufferRange range(nullptr, 1, size, 4); - EXPECT_EQ(range.size(), size); -} - -static void fill_buffer_with_indexes(float *buf, int buf_len) -{ - for (int i = 0; i < buf_len; i++) { - buf[i] = i; - } -} - -TEST(BufferRange, Subscript) -{ - const int start = 2; - const int size = 4; - const int num_channels = 3; - const int buf_len = (start + size) * num_channels; - float buf[buf_len]; - - BufferRange range(buf, start, size, num_channels); - - fill_buffer_with_indexes(buf, buf_len); - int buf_index = start * num_channels; - for (int i = 0; i < size; i++) { - const float *elem = range[i]; - for (int ch = 0; ch < num_channels; ch++) { - EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON); - buf_index++; - } - } - EXPECT_EQ(buf_index, buf_len); -} - -TEST(BufferRange, SingleElemBufferIteration) -{ - const int start = 1; - const int size = 3; - const int num_channels = 4; - float buf[num_channels]; - const int stride = 0; - BufferRange range(buf, start, size, stride); - - int elems_count = 0; - for (float *elem : range) { - EXPECT_EQ(elem, buf); - elems_count++; - } - EXPECT_EQ(elems_count, 1); -} - -TEST(BufferRange, FullBufferIteration) -{ - const int start = 2; - const int size = 5; - const int num_channels = 4; - const int buf_len = (start + size) * num_channels; - float buf[buf_len]; - BufferRange range(buf, start, size, num_channels); - - fill_buffer_with_indexes(buf, buf_len); - int buf_index = start * num_channels; - for (float *elem : range) { - for (int ch = 0; ch < num_channels; ch++) { - EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON); - buf_index++; - } - } - EXPECT_EQ(buf_index, buf_len); -} - -} // namespace blender::compositor::tests diff --git a/source/blender/compositor/tests/COM_BuffersIterator_test.cc b/source/blender/compositor/tests/COM_BuffersIterator_test.cc deleted file mode 100644 index 85f4e145c97..00000000000 --- a/source/blender/compositor/tests/COM_BuffersIterator_test.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "testing/testing.h" - -#include "BLI_array.hh" -#include "COM_BuffersIterator.h" - -namespace blender::compositor::tests { - -constexpr int BUFFER_WIDTH = 5; -constexpr int BUFFER_HEIGHT = 4; -constexpr int BUFFER_OFFSET_X = 5; -constexpr int BUFFER_OFFSET_Y = 6; -constexpr int NUM_CHANNELS = 4; -constexpr int FULL_BUFFER_LEN = BUFFER_WIDTH * BUFFER_HEIGHT * NUM_CHANNELS; -constexpr int SINGLE_ELEM_BUFFER_LEN = NUM_CHANNELS; -constexpr int NUM_INPUTS = 2; - -static float *create_buffer(int len) -{ - return (float *)MEM_callocN(len * sizeof(float), "COM_BuffersIteratorTest"); -} - -static const float *create_input_buffer(int input_idx, bool is_a_single_elem) -{ - const int len = is_a_single_elem ? SINGLE_ELEM_BUFFER_LEN : FULL_BUFFER_LEN; - float *buf = create_buffer(len); - /* Fill buffer with variable data. */ - for (int i = 0; i < len; i++) { - buf[i] = input_idx * 1.5f * (i + 1) + i * 0.9f; - } - return buf; -} - -using IterFunc = std::function &it, const rcti &area)>; -using ValidateElemFunc = std::function ins, int x, int y)>; - -class BuffersIteratorTest : public testing::Test { - private: - float *output_; - bool use_offsets_; - bool use_single_elem_inputs_; - bool use_inputs_; - - static rcti buffer_area; - static rcti buffer_offset_area; - static Array single_elem_inputs; - static Array full_buffer_inputs; - - public: - void set_inputs_enabled(bool value) - { - use_inputs_ = value; - } - - void test_iteration(IterFunc iter_func, ValidateElemFunc validate_elem_func = {}) - { - use_single_elem_inputs_ = false; - validate_iteration(iter_func, validate_elem_func); - if (use_inputs_) { - use_single_elem_inputs_ = true; - validate_iteration(iter_func, validate_elem_func); - } - } - - protected: - static void SetUpTestCase() - { - BLI_rcti_init(&buffer_area, 0, BUFFER_WIDTH, 0, BUFFER_HEIGHT); - BLI_rcti_init(&buffer_offset_area, - BUFFER_OFFSET_X, - BUFFER_OFFSET_X + BUFFER_WIDTH, - BUFFER_OFFSET_Y, - BUFFER_OFFSET_Y + BUFFER_HEIGHT); - for (int i = 0; i < NUM_INPUTS; i++) { - single_elem_inputs[i] = create_input_buffer(i, true); - full_buffer_inputs[i] = create_input_buffer(i, false); - } - } - - static void TearDownTestCase() - { - for (int i = 0; i < NUM_INPUTS; i++) { - MEM_freeN((void *)single_elem_inputs[i]); - single_elem_inputs[i] = nullptr; - MEM_freeN((void *)full_buffer_inputs[i]); - full_buffer_inputs[i] = nullptr; - } - } - - void SetUp() override - { - use_offsets_ = false; - use_single_elem_inputs_ = false; - use_inputs_ = false; - output_ = create_buffer(FULL_BUFFER_LEN); - } - - void TearDown() override - { - MEM_freeN(output_); - } - - private: - void validate_iteration(IterFunc iter_func, ValidateElemFunc validate_elem_func) - { - { - use_offsets_ = false; - BuffersIterator it = iterate(); - iter_func(it, buffer_area); - validate_result(buffer_area, validate_elem_func); - } - { - use_offsets_ = true; - BuffersIterator it = offset_iterate(buffer_offset_area); - iter_func(it, buffer_offset_area); - validate_result(buffer_offset_area, validate_elem_func); - } - { - use_offsets_ = true; - rcti area = buffer_offset_area; - area.xmin += 1; - area.ymin += 1; - area.xmax -= 1; - area.ymax -= 1; - BuffersIterator it = offset_iterate(area); - iter_func(it, area); - validate_result(area, validate_elem_func); - } - } - - void validate_result(rcti &area, ValidateElemFunc validate_elem_func) - { - Span inputs = get_inputs(); - Array ins(inputs.size()); - for (int y = area.ymin; y < area.ymax; y++) { - for (int x = area.xmin; x < area.xmax; x++) { - const int out_offset = get_buffer_relative_y(y) * BUFFER_WIDTH * NUM_CHANNELS + - get_buffer_relative_x(x) * NUM_CHANNELS; - float *out = &output_[out_offset]; - - const int in_offset = use_single_elem_inputs_ ? 0 : out_offset; - for (int i = 0; i < inputs.size(); i++) { - ins[i] = &inputs[i][in_offset]; - } - - if (validate_elem_func) { - validate_elem_func(out, ins, x, y); - } - } - } - } - - Span get_inputs() - { - if (use_inputs_) { - return use_single_elem_inputs_ ? single_elem_inputs : full_buffer_inputs; - } - return {}; - } - - int get_buffer_relative_x(int x) - { - return use_offsets_ ? x - BUFFER_OFFSET_X : x; - } - int get_buffer_relative_y(int y) - { - return use_offsets_ ? y - BUFFER_OFFSET_Y : y; - } - - /** Iterates whole buffers with no offsets. */ - BuffersIterator iterate() - { - BLI_assert(!use_offsets_); - BuffersIteratorBuilder builder(output_, BUFFER_WIDTH, BUFFER_HEIGHT, NUM_CHANNELS); - if (use_inputs_) { - const int input_stride = use_single_elem_inputs_ ? 0 : NUM_CHANNELS; - for (const float *input : get_inputs()) { - builder.add_input(input, BUFFER_WIDTH, input_stride); - } - } - return builder.build(); - } - - /** Iterates a given buffers area with default offsets. */ - BuffersIterator offset_iterate(const rcti &area) - { - BLI_assert(use_offsets_); - const rcti &buf_area = buffer_offset_area; - BuffersIteratorBuilder builder(output_, buf_area, area, NUM_CHANNELS); - if (use_inputs_) { - const int input_stride = use_single_elem_inputs_ ? 0 : NUM_CHANNELS; - for (const float *input : get_inputs()) { - builder.add_input(input, buf_area, input_stride); - } - } - return builder.build(); - } -}; - -rcti BuffersIteratorTest::buffer_area; -rcti BuffersIteratorTest::buffer_offset_area; -Array BuffersIteratorTest::single_elem_inputs(NUM_INPUTS); -Array BuffersIteratorTest::full_buffer_inputs(NUM_INPUTS); - -static void iterate_coordinates(BuffersIterator &it, const rcti &area) -{ - int x = area.xmin; - int y = area.ymin; - for (; !it.is_end(); ++it) { - EXPECT_EQ(x, it.x); - EXPECT_EQ(y, it.y); - x++; - if (x == area.xmax) { - x = area.xmin; - y++; - } - } - EXPECT_EQ(x, area.xmin); - EXPECT_EQ(y, area.ymax); -} - -TEST_F(BuffersIteratorTest, CoordinatesIterationWithNoInputs) -{ - set_inputs_enabled(false); - test_iteration(iterate_coordinates); -} - -TEST_F(BuffersIteratorTest, CoordinatesIterationWithInputs) -{ - set_inputs_enabled(true); - test_iteration(iterate_coordinates); -} - -TEST_F(BuffersIteratorTest, OutputIteration) -{ - set_inputs_enabled(false); - test_iteration( - [](BuffersIterator &it, const rcti & /*area*/) { - EXPECT_EQ(it.get_num_inputs(), 0); - for (; !it.is_end(); ++it) { - const int dummy = it.y * BUFFER_WIDTH + it.x; - it.out[0] = dummy + 1.0f; - it.out[1] = dummy + 2.0f; - it.out[2] = dummy + 3.0f; - it.out[3] = dummy + 4.0f; - } - }, - [](float *out, Span /*ins*/, const int x, const int y) { - const int dummy = y * BUFFER_WIDTH + x; - EXPECT_NEAR(out[0], dummy + 1.0f, FLT_EPSILON); - EXPECT_NEAR(out[1], dummy + 2.0f, FLT_EPSILON); - EXPECT_NEAR(out[2], dummy + 3.0f, FLT_EPSILON); - EXPECT_NEAR(out[3], dummy + 4.0f, FLT_EPSILON); - }); -} - -TEST_F(BuffersIteratorTest, OutputAndInputsIteration) -{ - set_inputs_enabled(true); - test_iteration( - [](BuffersIterator &it, const rcti & /*area*/) { - EXPECT_EQ(it.get_num_inputs(), NUM_INPUTS); - for (; !it.is_end(); ++it) { - const float *in1 = it.in(0); - const float *in2 = it.in(1); - it.out[0] = in1[0] + in2[0]; - it.out[1] = in1[1] + in2[3]; - it.out[2] = in1[2] - in2[2]; - it.out[3] = in1[3] - in2[1]; - } - }, - [](float *out, Span ins, const int /*x*/, const int /*y*/) { - const float *in1 = ins[0]; - const float *in2 = ins[1]; - EXPECT_NEAR(out[0], in1[0] + in2[0], FLT_EPSILON); - EXPECT_NEAR(out[1], in1[1] + in2[3], FLT_EPSILON); - EXPECT_NEAR(out[2], in1[2] - in2[2], FLT_EPSILON); - EXPECT_NEAR(out[3], in1[3] - in2[1], FLT_EPSILON); - }); -} - -} // namespace blender::compositor::tests diff --git a/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc b/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc deleted file mode 100644 index b4b63f596ef..00000000000 --- a/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* SPDX-FileCopyrightText: 2023 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "testing/testing.h" - -#include "COM_SummedAreaTableOperation.h" - -namespace blender::compositor::tests { - -struct SatParams { - /* Input parameters. */ - SummedAreaTableOperation::eMode mode; - rcti area; - float4 fill_value; - - /* Expected output values. */ - std::vector> values; -}; - -class SummedAreaTableTestP : public testing::TestWithParam {}; - -TEST_P(SummedAreaTableTestP, Values) -{ - SatParams params = GetParam(); - - SummedAreaTableOperation sat = SummedAreaTableOperation(); - - sat.set_mode(params.mode); - const rcti area = params.area; - MemoryBuffer output(DataType::Color, area); - - std::shared_ptr input = std::make_shared(DataType::Color, area); - input->fill(area, ¶ms.fill_value.x); - - sat.update_memory_buffer(&output, area, Span{input.get()}); - - /* First row. */ - EXPECT_FLOAT_EQ(output.get_elem(0, 0)[0], params.values[0][0]); - EXPECT_FLOAT_EQ(output.get_elem(1, 0)[1], params.values[0][1]); - EXPECT_FLOAT_EQ(output.get_elem(2, 0)[2], params.values[0][2]); - - /* Second row. */ - EXPECT_FLOAT_EQ(output.get_elem(0, 1)[3], params.values[1][0]); - EXPECT_FLOAT_EQ(output.get_elem(1, 1)[0], params.values[1][1]); - EXPECT_FLOAT_EQ(output.get_elem(2, 1)[1], params.values[1][2]); -} - -INSTANTIATE_TEST_SUITE_P(FullFrame5x2_IdentityOnes, - SummedAreaTableTestP, - testing::Values(SatParams{ - SummedAreaTableOperation::eMode::Identity, - rcti{0, 5, 0, 2}, /* Area. */ - {1.0f, 1.0f, 1.0f, 1.0f}, /* Fill value. */ - - /* Expected output. */ - {{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}, {2.0f, 4.0f, 6.0f, 8.0f, 10.0f}} - - })); - -INSTANTIATE_TEST_SUITE_P( - FullFrame5x2_SquaredOnes, - SummedAreaTableTestP, - testing::Values(SatParams{ - SummedAreaTableOperation::eMode::Squared, - rcti{0, 5, 0, 2}, /* Area. */ - {1.0f, 1.0f, 1.0f, 1.0f}, /* Fill value. */ - - /* Expect identical to when using Identity SAT, since all inputs are 1. */ - {{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}, {2.0f, 4.0f, 6.0f, 8.0f, 10.0f}} - - })); - -INSTANTIATE_TEST_SUITE_P(FullFrame3x2_Squared, - SummedAreaTableTestP, - testing::Values(SatParams{SummedAreaTableOperation::eMode::Squared, - rcti{0, 3, 0, 2}, /* Area. */ - {2.0f, 2.0f, 1.5f, .1f}, /* Fill value. */ - - /* Expected output. */ - { - {4.0f, 8.0f, 6.75f}, - {0.02f, 16.0f, 24.0f}, - }})); - -class SummedAreaTableSumTest : public ::testing::Test { - public: - SummedAreaTableSumTest() - { - operation_ = std::make_shared(); - } - - protected: - void SetUp() override - { - operation_->set_mode(SummedAreaTableOperation::eMode::Squared); - - area_ = rcti{0, 5, 0, 4}; - sat_ = std::make_shared(DataType::Color, area_); - - const float val[4] = {1.0f, 2.0f, 1.5f, 0.1f}; - std::shared_ptr input = std::make_shared(DataType::Color, area_); - input->fill(area_, val); - std::shared_ptr offset = std::make_shared( - DataType::Value, area_, true); - offset->fill(area_, &offset_); - - operation_->update_memory_buffer( - sat_.get(), area_, Span{input.get(), offset.get()}); - } - - std::shared_ptr operation_; - std::shared_ptr sat_; - rcti area_; - float offset_ = 0.0f; -}; - -TEST_F(SummedAreaTableSumTest, FullyInside) -{ - rcti area; - area.xmin = 1; - area.xmax = 3; - area.ymin = 1; - area.ymax = 3; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 9); -} - -TEST_F(SummedAreaTableSumTest, LeftEdge) -{ - rcti area; - area.xmin = 0; - area.xmax = 2; - area.ymin = 0; - area.ymax = 2; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 9); -} - -TEST_F(SummedAreaTableSumTest, RightEdge) -{ - rcti area; - area.xmin = area_.xmax - 2; - area.xmax = area_.xmax; - area.ymin = 0; - area.ymax = 2; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 6); -} - -TEST_F(SummedAreaTableSumTest, LowerRightCorner) -{ - rcti area; - area.xmin = area_.xmax - 1; - area.xmax = area_.xmax; - area.ymin = area_.ymax - 1; - area.ymax = area_.ymax; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 1); -} - -TEST_F(SummedAreaTableSumTest, TopLine) -{ - rcti area; - area.xmin = 0; - area.xmax = 1; - area.ymin = 0; - area.ymax = 0; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 2); -} - -TEST_F(SummedAreaTableSumTest, ButtomLine) -{ - rcti area; - area.xmin = 0; - area.xmax = 4; - area.ymin = 3; - area.ymax = 3; - float4 sum = summed_area_table_sum(sat_.get(), area); - EXPECT_EQ(sum[0], 5); -} - -} // namespace blender::compositor::tests diff --git a/source/blender/compositor/tests/COM_NodeOperation_test.cc b/source/blender/compositor/tests/COM_NodeOperation_test.cc deleted file mode 100644 index efb2488ab60..00000000000 --- a/source/blender/compositor/tests/COM_NodeOperation_test.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* SPDX-FileCopyrightText: 2021 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "testing/testing.h" - -#include "COM_ConstantOperation.h" - -namespace blender::compositor::tests { - -class NonHashedOperation : public NodeOperation { - public: - NonHashedOperation(int id) - { - set_id(id); - add_output_socket(DataType::Value); - set_canvas({0, 2, 0, 3}); - } -}; - -class NonHashedConstantOperation : public ConstantOperation { - float constant_; - - public: - NonHashedConstantOperation(int id) - { - set_id(id); - add_output_socket(DataType::Value); - set_canvas({0, 2, 0, 3}); - constant_ = 1.0f; - } - - const float *get_constant_elem() override - { - return &constant_; - } - - void set_constant(float value) - { - constant_ = value; - } -}; - -class HashedOperation : public NodeOperation { - private: - int param1; - float param2; - - public: - HashedOperation(NodeOperation &input, int width, int height) - { - add_input_socket(DataType::Value); - add_output_socket(DataType::Color); - set_canvas({0, width, 0, height}); - param1 = 2; - param2 = 7.0f; - - get_input_socket(0)->set_link(input.get_output_socket()); - } - - void set_param1(int value) - { - param1 = value; - } - - void hash_output_params() override - { - hash_params(param1, param2); - } -}; - -static void test_non_equal_hashes_compare(NodeOperationHash &h1, - NodeOperationHash &h2, - NodeOperationHash &h3) -{ - if (h1 < h2) { - if (h3 < h1) { - EXPECT_TRUE(h3 < h2); - } - else if (h3 < h2) { - EXPECT_TRUE(h1 < h3); - } - else { - EXPECT_TRUE(h1 < h3); - EXPECT_TRUE(h2 < h3); - } - } - else { - EXPECT_TRUE(h2 < h1); - } -} - -TEST(NodeOperation, generate_hash) -{ - /* Constant input. */ - { - NonHashedConstantOperation input_op1(1); - input_op1.set_constant(1.0f); - EXPECT_EQ(input_op1.generate_hash(), std::nullopt); - - HashedOperation op1(input_op1, 6, 4); - std::optional hash1_opt = op1.generate_hash(); - EXPECT_NE(hash1_opt, std::nullopt); - NodeOperationHash hash1 = *hash1_opt; - - NonHashedConstantOperation input_op2(1); - input_op2.set_constant(1.0f); - HashedOperation op2(input_op2, 6, 4); - NodeOperationHash hash2 = *op2.generate_hash(); - EXPECT_EQ(hash1, hash2); - - input_op2.set_constant(3.0f); - hash2 = *op2.generate_hash(); - EXPECT_NE(hash1, hash2); - } - - /* Non constant input. */ - { - NonHashedOperation input_op(1); - EXPECT_EQ(input_op.generate_hash(), std::nullopt); - - HashedOperation op1(input_op, 6, 4); - HashedOperation op2(input_op, 6, 4); - NodeOperationHash hash1 = *op1.generate_hash(); - NodeOperationHash hash2 = *op2.generate_hash(); - EXPECT_EQ(hash1, hash2); - op1.set_param1(-1); - hash1 = *op1.generate_hash(); - EXPECT_NE(hash1, hash2); - - HashedOperation op3(input_op, 11, 14); - NodeOperationHash hash3 = *op3.generate_hash(); - EXPECT_NE(hash2, hash3); - EXPECT_NE(hash1, hash3); - - test_non_equal_hashes_compare(hash1, hash2, hash3); - test_non_equal_hashes_compare(hash3, hash2, hash1); - test_non_equal_hashes_compare(hash2, hash3, hash1); - test_non_equal_hashes_compare(hash3, hash1, hash2); - - NonHashedOperation input_op2(2); - HashedOperation op4(input_op2, 11, 14); - NodeOperationHash hash4 = *op4.generate_hash(); - EXPECT_NE(hash3, hash4); - - input_op2.set_id(1); - hash4 = *op4.generate_hash(); - EXPECT_EQ(hash3, hash4); - } -} - -} // namespace blender::compositor::tests diff --git a/tools/check_source/check_cmake_consistency_config.py b/tools/check_source/check_cmake_consistency_config.py index 2b535b1a2e1..b844430f33b 100644 --- a/tools/check_source/check_cmake_consistency_config.py +++ b/tools/check_source/check_cmake_consistency_config.py @@ -19,7 +19,6 @@ IGNORE_SOURCE = ( "source/creator/blender_launcher_win32.c", # Pre-computed headers. - "source/blender/compositor/COM_precomp.h", "source/blender/freestyle/FRS_precomp.h", # Specific source files.