### Manual Build Steps with CMake Source: https://github.com/academysoftwarefoundation/openfx/blob/main/install.md Steps for manually building OpenFX using Conan for dependency installation and CMake for configuration and building. ```shell % cd $TOPLEVEL # where CMakeLists.txt is located # Install dependencies from conanfile.py % conan install -s build_type=Release -pr:b=default --build=missing . # Configure cmake to build into Build folder, and build example plugins % cmake --preset conan-release -DBUILD_EXAMPLE_PLUGINS=TRUE # Do the build % cmake --build build/Release --config Release --parallel # Install the plugins locally (may require root privs) % cmake --build build/Release --target install --config Release ``` -------------------------------- ### Clip Instance Frame Range and FPS Reporting Example 1 Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxCoordSystem.md Shows the reported frame ranges and frame rates for output and source clip instances in a scenario where the effect starts at clip frame 5 and has a duration of 10 frames, with identical input and output frame rates. ```text range[0] range[1] FPS Output 0 9 25 Source -4 15 25 ``` -------------------------------- ### Install CMake for Different OS Source: https://github.com/academysoftwarefoundation/openfx/blob/main/install.md Commands to install CMake on macOS, Windows, and Linux. ```shell brew install cmake ``` ```shell choco install cmake ``` ```shell apt install cmake ``` -------------------------------- ### Specifying Choice Parameter Order (v2 Example) Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxParameter.md Demonstrates how to define the display order of choice parameter options using kOfxParamPropChoiceOrder for backward compatibility and UI flexibility in new plugin versions. ```cpp // Plugin v1: // Option = {"OptA", "OptB", "OptC"} // Order = {0, 1, 2} // default, or explicit // Plugin v2: // add NewOpt at the end of the list, but specify order so it comes one before the end in the UI // Will display OptA / OptB / NewOpt / OptC // Option = {"OptA", "OptB", "OptC", "NewOpt"} // Order = {0, 1, 3, 2} // or anything that sorts the same, e.g. {1, 100, 300, 200} ``` -------------------------------- ### Use Host-Specific Properties Source: https://github.com/academysoftwarefoundation/openfx/blob/main/openfx-cpp/examples/host-specific-props/README.md Demonstrates how a plugin can use the `PropertyAccessor` to get a host-specific property, including error handling for when the property is not found. ```cpp using namespace openfx; void describe(OfxImageEffectHandle effect, const SuiteContainer& suites) { PropertyAccessor props(effect, suites); // Standard OpenFX property props.set("My Effect"); // Host-specific property (fully qualified) try { auto value = props.get(0, false); Logger::info("Host property value: {}", value); } catch (const PropertyNotFoundException&) { // Not running in MyHost, or property not supported } } ``` -------------------------------- ### Doxygen Cross-references Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/README.md Create links to other documentation elements within Doxygen comments using \ref. ```c /** See \ref kOfxImageEffectPropSupportedPixelDepths */ ``` -------------------------------- ### Clip Instance Frame Range and FPS Reporting Example 2 Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxCoordSystem.md Presents the reported frame ranges and frame rates for output and source clip instances in a scenario where the output frame rate is double the input frame rate. ```text range[0] range[1] FPS Output 0 9 50 Source -2 12 25 ``` -------------------------------- ### Define Custom Properties in YAML Source: https://github.com/academysoftwarefoundation/openfx/blob/main/openfx-cpp/examples/host-specific-props/README.md Example of a YAML file defining custom host properties, including their name, type, dimension, description, and valid contexts. ```yaml # myhost-props.yml properties: MyHostCustomProperty: name: "com.mycompany.myhost.CustomProperty" type: string dimension: 1 description: "Description of the custom property" valid_for: - "Effect Descriptor" - "Effect Instance" ``` -------------------------------- ### OpenFX Suite Function Signature Example Source: https://github.com/academysoftwarefoundation/openfx/wiki/Extending-OpenFX-Guidelines Suite functions must include an inArgs PropertySet handle to maintain host context awareness during concurrent renders. Functions without this parameter will be declined. ```c int (*abort)(OfxImageEffectHandle imageEffect, OfxPropertySetHandle actionInArgs); ``` -------------------------------- ### OFX Image Memory Allocation Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxImageClip.md Demonstrates the process of allocating, locking, using, unlocking, and freeing custom image memory buffers using OFX image effect suite functions. Note that memory addresses may change between lock/unlock cycles. ```default // get a memory handle OfxImageMemoryHandle memHandle; gEffectSuite->imageMemoryAlloc(0, imageSize, &memHandle); // lock the handle and get a pointer void *memPtr; gEffectSuite->imageMemoryLock(memHandle, &memPtr); ... // do stuff with our pointer // now unlock it gEffectSuite->imageMemoryUnlock(memHandle); // lock it again, note that this may give a completely different address to the last lock gEffectSuite->imageMemoryLock(memHandle, &memPtr); ... // do more stuff // unlock it again gEffectSuite->imageMemoryUnlock(memHandle); // delete it all gEffectSuite->imageMemoryFree(memHandle); ``` -------------------------------- ### Get Standard OpenFX Plugin Path (Windows) Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxPackaging.md Retrieves the default installation path for OpenFX plugins on Windows systems. This function is used to locate plugins in the common program files directory. ```c #include "shlobj.h" #include "tchar.h" const TCHAR *getStdOFXPluginPath(void) { static TCHAR buffer[MAX_PATH]; static int gotIt = 0; if(!gotIt) { gotIt = 1; SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, SHGFP_TYPE_CURRENT, buffer); _tcscat(buffer, __T("\OFX\Plugins")); } return buffer; } ``` -------------------------------- ### Effect and Source Clip Frame Ranges Example 1 Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxCoordSystem.md Illustrates the frame ranges of an effect and its source clip when the effect duration is 10 frames and the clip duration is 20 frames, with the effect starting at the 5th frame of the clip. Both input and output have the same frame rate. ```text Effect 0 1 2 3 4 5 6 7 8 9 Source 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ``` -------------------------------- ### Fetching Suites from Host Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample1_Basics.md Demonstrates how a plugin retrieves core suites (Property and Image Effect) from the host application during the LoadAction. This is essential for subsequent plugin operations. ```c++ // The anonymous namespace is used to hide symbols from export. namespace { OfxHost *gHost; OfxPropertySuiteV1 *gPropertySuite = 0; OfxImageEffectSuiteV1 *gImageEffectSuite = 0; //////////////////////////////////////////////////////////////////////////////// /// call back passed to the host in the OfxPlugin struct to set our host pointer void SetHostFunc(OfxHost *hostStruct) { gHost = hostStruct; } //////////////////////////////////////////////////////////////////////////////// /// the first action called OfxStatus LoadAction(void) { gPropertySuite = (OfxPropertySuiteV1 *) gHost->fetchSuite(gHost->host, kOfxPropertySuite, 1); gImageEffectSuite = (OfxImageEffectSuiteV1 *) gHost->fetchSuite(gHost->host, kOfxImageEffectSuite, 1); return kOfxStatOK; } } ``` -------------------------------- ### Fetch and Initialize OpenFX Suites Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample3_Gain.md This C++ code snippet shows how to fetch essential OpenFX suites (Property, ImageEffect, and Parameter) using a helper function. It's used during the plugin's load action to ensure all required host functionalities are available. ```c++ OfxPropertySuiteV1 *gPropertySuite = 0; OfxImageEffectSuiteV1 *gImageEffectSuite = 0; OfxParameterSuiteV1 *gParameterSuite = 0; //////////////////////////////////////////////////////////////////////////////// // get the named suite and put it in the given pointer, with error checking template void FetchSuite(SUITE *& suite, const char *suiteName, int suiteVersion) { suite = (SUITE *) gHost->fetchSuite(gHost->host, suiteName, suiteVersion); if(!suite) { ERROR_ABORT_IF(suite == NULL, "Failed to fetch %s version %d from the host.", suiteName, suiteVersion); } } //////////////////////////////////////////////////////////////////////////////// // The first _action_ called after the binary is loaded OfxStatus LoadAction(void) { // fetch our three suites FetchSuite(gPropertySuite, kOfxPropertySuite, 1); FetchSuite(gImageEffectSuite, kOfxImageEffectSuite, 1); FetchSuite(gParameterSuite, kOfxParameterSuite, 1); return kOfxStatOK; } ``` -------------------------------- ### Install Conan using pip Source: https://github.com/academysoftwarefoundation/openfx/blob/main/install.md Command to install Conan version 2.1.0 or later using pip and python3. ```shell python3 -mpip install 'conan>=2.1.0' ``` -------------------------------- ### Include Host and Core Headers Source: https://github.com/academysoftwarefoundation/openfx/blob/main/openfx-cpp/examples/host-specific-props/README.md Shows the necessary include directives for a plugin to access both OpenFX core properties and host-specific properties. ```cpp #include // OpenFX core #include // Host-specific ``` -------------------------------- ### ReStructured Text Code Block Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/README.md Embed code examples within RST documentation using the .. code-block:: directive, specifying the language. ```rst .. code-block:: c #define kOfxImageEffectPropSupportsMultiResolution "OfxImageEffectPluginRenderThreadSafety" ``` -------------------------------- ### OfxActionCreateInstance Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxPropertySetsGenerated.md Initiates the creation of a new instance. This action has no input or output arguments. ```APIDOC ## OfxActionCreateInstance ### Description Initiates the creation of a new instance. This action has no input or output arguments. ``` -------------------------------- ### Create Plugin Instance Action Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample1_Basics.md This C++ code demonstrates the `kOfxActionCreateInstance` action. It attaches custom string data to the plugin instance using `kOfxPropInstanceData`. ```c++ OfxStatus CreateInstanceAction(OfxImageEffectHandle instance) { OfxPropertySetHandle effectProps; gImageEffectSuite->getPropertySet(instance, &effectProps); // attach some instance data to the effect handle, it can be anything char *myString = strdup("This is random instance data that could be anything you want."); // set my private instance data gPropertySuite->propSetPointer(effectProps, kOfxPropInstanceData, 0, (void *) myString); return kOfxStatOK; } ``` -------------------------------- ### Create Instance Action Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample3_Gain.md Handles the creation of a plugin instance by allocating and caching private instance data. It retrieves and stores handles for source and output clips, as well as gain and alpha parameters, for later use. ```c++ //////////////////////////////////////////////////////////////////////////////// /// instance construction OfxStatus CreateInstanceAction( OfxImageEffectHandle instance) { OfxPropertySetHandle effectProps; gImageEffectSuite->getPropertySet(instance, &effectProps); // To avoid continual lookup, put our handles into our instance // data, those handles are guaranteed to be valid for the duration // of the instance. MyInstanceData *myData = new MyInstanceData; // Set my private instance data gPropertySuite->propSetPointer(effectProps, kOfxPropInstanceData, 0, (void *) myData); // Cache the source and output clip handles gImageEffectSuite->clipGetHandle(instance, "Source", &myData->sourceClip, 0); gImageEffectSuite->clipGetHandle(instance, "Output", &myData->outputClip, 0); // Cache away the param handles OfxParamSetHandle paramSet; gImageEffectSuite->getParamSet(instance, ¶mSet); gParameterSuite->paramGetHandle(paramSet, GAIN_PARAM_NAME, &myData->gainParam, 0); gParameterSuite->paramGetHandle(paramSet, APPLY_TO_ALPHA_PARAM_NAME, &myData->applyToAlphaParam, 0); return kOfxStatOK; } ``` -------------------------------- ### Set Supported Contexts for the Effect Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample4_Saturation.md Sets the contexts in which the image effect can be used. This example specifies 'Filter' and 'General' contexts. ```default // Define the image effects contexts we can be used in, in this case a filter // and a general effect. gPropertySuite->propSetString(effectProps, kOfxImageEffectPropSupportedContexts, 0, kOfxImageEffectContextFilter); gPropertySuite->propSetString(effectProps, kOfxImageEffectPropSupportedContexts, 1, kOfxImageEffectContextGeneral); ``` -------------------------------- ### Handle Get Region Of Definition Action in MainEntry Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample5_Circle.md Conditionally calls the GetRegionOfDefinitionAction if the host supports multi-resolution and the action is kOfxImageEffectActionGetRegionOfDefinition. ```c++ else if(gHostSupportsMultiRes && strcmp(action, kOfxImageEffectActionGetRegionOfDefinition) == 0) { returnStatus = GetRegionOfDefinitionAction(effect, inArgs, outArgs); } ``` -------------------------------- ### Add OpenFX Subdirectories Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Support/CMakeLists.txt Includes the 'Library' subdirectory for building. Conditionally adds 'Plugins' and 'PropTester' subdirectories if 'BUILD_EXAMPLE_PLUGINS' is enabled. ```cmake add_subdirectory(Library) ``` ```cmake if(BUILD_EXAMPLE_PLUGINS) add_subdirectory(Plugins) add_subdirectory(PropTester) endif() ``` -------------------------------- ### Main Entry Point for OpenFX Plugins Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample1_Basics.md This C++ code demonstrates the MainEntryPoint function, which serves as the primary interface for handling various actions requested by the host application. It includes logic for common actions like loading, unloading, describing, and instance management. ```c++ OfxStatus MainEntryPoint(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) { // cast to appropriate type OfxImageEffectHandle effect = (OfxImageEffectHandle) handle; OfxStatus returnStatus = kOfxStatReplyDefault; if(strcmp(action, kOfxActionLoad) == 0) { returnStatus = LoadAction(); } else if(strcmp(action, kOfxActionUnload) == 0) { returnStatus = UnloadAction(); } else if(strcmp(action, kOfxActionDescribe) == 0) { returnStatus = DescribeAction(effect); } else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) { returnStatus = DescribeInContextAction(effect, inArgs); } else if(strcmp(action, kOfxActionCreateInstance) == 0) { returnStatus = CreateInstanceAction(effect); } else if(strcmp(action, kOfxActionDestroyInstance) == 0) { returnStatus = DestroyInstanceAction(effect); } else if(strcmp(action, kOfxImageEffectActionIsIdentity) == 0) { returnStatus = IsIdentityAction(effect, inArgs, outArgs); } return returnStatus; } ``` -------------------------------- ### Add OfxHost Static Library Source: https://github.com/academysoftwarefoundation/openfx/blob/main/HostSupport/CMakeLists.txt Creates a static library named 'OfxHost' including all found header and source files. Static libraries are linked directly into the executable. ```cmake add_library(OfxHost STATIC ${OFX_HEADER_FILES} ${OFX_HOSTSUPPORT_HEADER_FILES} ${OFX_HOSTSUPPORT_LIBRARY_FILES}) ``` -------------------------------- ### OfxImageEffectActionGetRegionsOfInterest Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Reference/ofxPropertySetsGenerated.md Gets the regions of interest for an image effect. This action considers the current time, render scale, and thumbnail rendering status. ```APIDOC ## OfxImageEffectActionGetRegionsOfInterest ### Description Gets the regions of interest for an image effect. ### Input Arguments - **OfxPropTime** (double) - The current time. - **OfxImageEffectPropRenderScale** (double[2]) - The render scale. - **OfxImageEffectPropRegionOfInterest** (double[4]) - The region of interest. - **OfxImageEffectPropThumbnailRender** (enum) - Indicates if thumbnail rendering is active. ``` -------------------------------- ### Define Plugin List Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Examples/CMakeLists.txt Lists the names of the plugins to be built. Each name corresponds to a plugin directory. ```cmake set(PLUGINS Basic ChoiceParams ColourSpace Custom DepthConverter Invert OpenGL Rectangle Test DrawSuite ) ``` -------------------------------- ### Main Entry Point Function for OFX Plugin Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample2_Invert.md This C++ function serves as the main entry point for an OFX plugin, handling various actions such as loading, describing, and rendering. ```c++ //////////////////////////////////////////////////////////////////////////////// // The main entry point function, the host calls this to get the plugin to do things. OfxStatus MainEntryPoint(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) { // cast to appropriate type OfxImageEffectHandle effect = (OfxImageEffectHandle) handle; OfxStatus returnStatus = kOfxStatReplyDefault; if(strcmp(action, kOfxActionLoad) == 0) { // The very first action called on a plugin. returnStatus = LoadAction(); } else if(strcmp(action, kOfxActionDescribe) == 0) { // the first action called to describe what the plugin does returnStatus = DescribeAction(effect); } else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) { // the second action called to describe what the plugin does returnStatus = DescribeInContextAction(effect, inArgs); } else if(strcmp(action, kOfxImageEffectActionRender) == 0) { // action called to render a frame returnStatus = RenderAction(effect, inArgs, outArgs); } /// other actions to take the default value return returnStatus; } } // end of anonymous namespace ``` -------------------------------- ### Find OpenFX Package with CMake Source: https://github.com/academysoftwarefoundation/openfx/blob/main/test_package/CMakeLists.txt Use this command to locate and import the OpenFX package configuration. Ensure OpenFX is installed and discoverable by CMake. ```cmake find_package(openfx CONFIG REQUIRED) ``` -------------------------------- ### Standard Copyright and License Header Source: https://github.com/academysoftwarefoundation/openfx/blob/main/CONTRIBUTING.md All new source files must begin with this SPDX-License-Identifier and copyright notice. ```c++ // // SPDX-License-Identifier: BSD-3-Clause // Copyright (c) OpenFX and contributors to the OpenFX Project. // ``` -------------------------------- ### ReStructured Text Internal Links Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/README.md Create internal references within RST documents using explicit targets and the :ref: role. ```rst .. _target-name: Section Title ============ See :ref:`target-name` for more information. ``` -------------------------------- ### ReStructured Text Section Headers Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/README.md Define document hierarchy in ReStructured Text (RST) using underline styles for section and subsection titles. ```rst Section Title ============ Subsection Title --------------- ``` -------------------------------- ### Create Instance Action for Saturation Effect Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/sources/Guide/ofxExample4_Saturation.md Handles the construction of a plugin instance, caching clip and parameter handles, and determining the effect's context. It specifically caches the 'Mask' input for general context effects. ```c++ //////////////////////////////////////////////////////////////////////////////// /// instance construction OfxStatus CreateInstanceAction( OfxImageEffectHandle instance) { OfxPropertySetHandle effectProps; gImageEffectSuite->getPropertySet(instance, &effectProps); // To avoid continual lookup, put our handles into our instance // data, those handles are guaranteed to be valid for the duration // of the instance. MyInstanceData *myData = new MyInstanceData; // Set my private instance data gPropertySuite->propSetPointer(effectProps, kOfxPropInstanceData, 0, (void *) myData); // is this instance made for the general context? char *context = 0; gPropertySuite->propGetString(effectProps, kOfxImageEffectPropContext, 0, &context); myData->isGeneralContext = context && (strcmp(context, kOfxImageEffectContextGeneral) == 0); // Cache the source and output clip handles gImageEffectSuite->clipGetHandle(instance, "Source", &myData->sourceClip, 0); gImageEffectSuite->clipGetHandle(instance, "Output", &myData->outputClip, 0); if(myData->isGeneralContext) { gImageEffectSuite->clipGetHandle(instance, "Mask", &myData->maskClip, 0); } // Cache away the param handles OfxParamSetHandle paramSet; gImageEffectSuite->getParamSet(instance, ¶mSet); gParameterSuite->paramGetHandle(paramSet, SATURATION_PARAM_NAME, &myData->saturationParam, 0); return kOfxStatOK; } ``` -------------------------------- ### Doxygen Groups Example Source: https://github.com/academysoftwarefoundation/openfx/blob/main/Documentation/README.md Organize related C++ API items using Doxygen groups. Ensure items are correctly added to the desired group. ```c /** \defgroup PropertiesAll Property Suite */ /** \ingroup PropertiesAll */ /** \addtogroup PropertiesAll @{ ... @} */ ```