Setup

Building from source

While there are an almost infinite number of setups, the following steps should cover many common setups.

The basic requirements are:

  • cmake >= 2.8
  • (optional) Python 2.x (for the Python bindings)
  • (optional) Nuke 6.x (for the Nuke nodes)
  • (optional) OpenImageIO (for apps including ocioconvert)
  • (optional) Truelight SDK (for TruelightTransform)

In the OCIO source directory, make a build directory (optionally, but highly recommended):

$ mkdir build && cd build

Then run cmake:

$ cmake -D CMAKE_INSTALL_PREFIX=install ../

You should see something along the lines of:

-- Configuring done
-- Generating done
-- Build files have been written to: .../build

Next, to build (with the -j flag to build using 8 CPU cores):

make -j8

Finally, to install into the CMAKE_INSTALL_PREFIX (the “install” directory):

make install

If nothing went wrong, you should now have an include/ directory containing the OpenColorIO headers, and a lib/ directory containing the libOpenColorIO library (a .dylib, .so or .dll file)

Enabling optional components

The OpenColourIO library is probably not all you want - the Python libraries bindings, the Nuke nodes and other included applications are only built if their dependencies are found.

In the case of the Python bindings, the dependencies are the Python headers for the version you wish to use. These may be picked up by default - if so, when you run cmake, you would see:

-- Python 2.6 okay, will build the Python bindings against .../include/python2.6

If not, you can point cmake to correct Python executable using the -D PYTHON=... cmake flag:

$ cmake -D PYTHON=/my/custom/python2.6

Same process with Nuke (although it less likely to be picked up automatically). Point cmake to your Nuke install directory using -D NUKE_INSTALL_PATH:

$ cmake -D NUKE_INSTALL_PATH=/Applications/Nuke6.2v1/Nuke6.2v1.app/Contents/MacOS/

The NUKE_INSTALL_PATH directory should contain the Nuke executable (e.g Nuke6.2v1), and a include/ directory containing DDImage/ and others.

If set correctly, you will see something similar to:

-- Found Nuke: /Applications/Nuke6.2v1/Nuke6.2v1.app/Contents/MacOS/include
-- Nuke_DDImageVersion: --6.2v1--

The Nuke plugins are installed into lib/$NUKE_VERSION/, e.g lib/nuke6.2v1/OCIODisdplay.so

Note that if you are using the Nuke plugins, you should compile the Python bindings for the same version of Python that Nuke uses internally. For Nuke 6.0 and 6.1 this is Python 2.5, and for 6.2 it is Python 2.6

The applications included with OCIO have various dependencies - to determine these, look at the CMake output when first run:

-- Not building ocioconvert. Requirement(s) found: OIIO:FALSE

Environment setup

OCIO

This env needs to point to the global profile.yaml

DYLD_LIBRARY_PATH

The lib/ folder (containing libOpenColorIO.dylib) must be on the DYLD_LIBRARY_PATH search path, or you will get an error similar to:

dlopen(.../OCIOColorSpace.so, 2): Library not loaded: libOpenColorIO.dylib
Referenced from: .../OCIOColorSpace.so
Reason: image not found

This applies to anything that links against OCIO, including the Nuke nodes, and the PyOpenColorIO Python bindings.

LD_LIBRARY_PATH

Equivalent to the DYLD_LIBRARY_PATH on Linux

PYTHONPATH

Python’s module search path. If you are using the PyOpenColorIO module, you must add lib/python2.x to this search path (e.g python/2.5), or importing the module will fail:

>>> import PyOpenColorIO
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named PyOpenColorIO

Note that DYLD_LIBRARY_PATH or LD_LIBRARY_PATH must be set correctly for the module to work.

NUKE_PATH

Nuke’s customisation search path, where it will look for plugins, gizmos, init.py and menu.py scripts and other customisations.

For information on setting this for OCIO, see Nuke Configuration

Nuke Configuration

If you build the OCIO Nuke plugins, they will be installed into lib/$NUKE_VERSION (for example: lib/nuke6.2v1). The bear-minimum required to use the plugins is to point the NUKE_PATH environment variable to this directory.

However, you probably want to load the plugins, and add them to the menu - so also add $BUILD_DIR/share/nuke to NUKE_PATH, and when Nuke is run it will execute two scripts, init.py which automatically loads all OCIO plugins, and menu.py which adds them to a OCIO menu under the Color node menu.

The OCIO workflow within Nuke is a different topic, but one common setup step is to register an OCIODisplay node as a viewer process (to apply a viewer LUT)

To do this, we you use the OCIO Python bindings to find all configured display devices (e.g sRGB device, DCIP3 device) and transforms (e.g Film emulation, raw and log), then register a viewer processor each combination.

The following function is defined in the OCIO-supplied menu.py file, so you can simply call ocio_populate_viewer() in a custom menu.py file (e.g in ~/.nuke/menu)

Alternatively, if your workflow has different requirements, you can copy the code and modify it as required, or use it as reference to write your own, better viewer setup function!

def ocio_populate_viewer(remove_nuke_default = True):
    """Registers the a viewer process for each display/transform, and
    sets the default

    Also unregisters the default Nuke viewer processes (sRGB/rec709)
    unless remove_nuke_default is False
    """

    # TODO: How to we unregister all? This assumes no other luts
    # have been registered by other viewer processes
    if remove_nuke_default:
        nuke.ViewerProcess.unregister('rec709')
        nuke.ViewerProcess.unregister('sRGB')


    # Formats the display and transform, e.g "Film1D (sRGB)"
    DISPLAY_UI_FORMAT = "%(view)s (%(display)s)"

    import PyOpenColorIO as OCIO
    config = OCIO.GetCurrentConfig()

    # For every display, loop over every view
    for display in config.getDisplays():
        for view in config.getViews(display):
            nuke.ViewerProcess.register(
                name = DISPLAY_UI_FORMAT % {'view': view, "display": display},
                call = nuke.nodes.OCIODisplay,
                args = (),
                kwargs = {"display": display, "view": view})


    # Get the default display and view, register it as the
    # default used on Nuke startup
    defaultDisplay = config.getDefaultDisplay()
    defaultView = config.getDefaultView(defaultDisplay)

    nuke.knobDefault(
        "Viewer.viewerProcess",
        DISPLAY_UI_FORMAT % {'view': defaultView, "display": defaultDisplay})