Look File Baking

New in Katana 4: The LookFileBakeAPI Python module now provides facilities for baking Look Files.

Introduction

The LookFileBakeAPI Python module provides facilities for baking Look Files, and for implementing custom output formats for use with nodes that make use of this API, such as the LookFileBake node, allowing users to write Look Files in custom data formats other than the built-in .klf formats.

LookFileBakeAPI.LookFileBaker may be used in combination with Nodes3DAPI.LookFileBaking to create custom Look-File-baking nodes.

Output Format Plug-ins

Registered LookFileBake output formats are listed as options for the option.outputFormat parameter of LookFileBake nodes.

Katana ships with two built-in output formats: as archive (classic .klf files) and as directory (directory containing pairs of .klf and .attrs files, one pair per pass). These output formats make use of the LookFileBakeAPI internally.

A third output format, as USD, is available as part of the Examples plug-ins (source code also available, see UsdLookFileBake.py). To make this format available for users to choose in LookFileBake nodes, add the path of the Examples folder to the KATANA_RESOURCES environment variable. The USD output format is a basic example that writes .usda files.

Note

The USD LookFileBake output format will only be available if the USD library’s Python modules have been added to the PYTHONPATH environment variable.

JSON LookFileBake Output Format Example

The JSON LookFileBake output format is a simple example to demonstrate how LookFileBake output formats can be plugged in into Katana.

This format outputs a directory. For each pass, a JSON file containing the pass data will be written into the directory (previously specified by the user).

To make this format available, copy the code below into a Python file inside the Plugins/ directory in one of the configured Katana resources. Alternatively, this code can be executed in a Python tab (note that if the format has been previously registered, it will have to be unregistered with LookFileBakeAPI.UnregisterOutputFormat() first).

import json
import os

import LookFileBakeAPI
from Katana import FnAttribute

class JsonLookFileBakeOutputFormat(
        LookFileBakeAPI.BaseLookFileBakeOutputFormat):
    """
    Class implementing a simple JSON LookFileBake output format.
    """

    # Class Variables ---------------------------------------------------------

    DisplayName = "as JSON"
    FileExtension = ""
    PassFileExtension = "json"

    # Instance Methods --------------------------------------------------------

    def writeSinglePass(self, passData):
        """
        @type passData: :py:obj:`LookFileBakeAPI.LookFilePassData`
        @rtype: :py:obj:`list` of :py:obj:`str`
        @param passData: The data representing a single Look File pass to be
            baked.
        @return: A list of paths to files which have been written.
        """
        # Create a JSON document from the given data.
        jsonPassData = {}
        jsonPassData["passName"] = passData.passName
        materialDict = {}
        jsonPassData["materialDict"] = materialDict
        for materialLocation, (locationType, attributes) in \
                passData.materialDict.items():
            materialDict[materialLocation] = {
                "type": locationType,
                "attributes": JsonLookFileBakeOutputFormat.attrToDict(
                    attributes)
            }
        # TODO: Also add passData.outputDictList, passData.rootOverrideDict
        # and passData.sharedOverridesDict.

        # Generate text that will ultimately be written into the text file.
        text = json.dumps(jsonPassData, indent=4)

        # Get the file path for this pass from the given pass data.
        filePath = passData.filePath

        # If the enclosing directory doesn't exist, then try to create it.
        dirPath = os.path.dirname(filePath)
        if not os.path.exists(dirPath):
            os.makedirs(dirPath)

        # Finally write the string containing the pass data into the file.
        with open(filePath, "w") as outFile:
            outFile.write(text)

        return [filePath]

    # Static Methods ----------------------------------------------------------

    @staticmethod
    def attrToDict(attribute):
        """
        Helper static method that converts an :py:obj:`FnAttribute` attribute into a
        Python dictionary.

        @type attribute: :py:obj:`FnAttribute` or :py:obj:`None`
        @param attribute: The attribute to be converted.
        @rtype: :py:obj:`dict`
        @return: The dictionary representing the given attribute.
        """
        result = {}

        # Early out if not a valid attribute.
        if attribute is None:
            return result

        if isinstance(attribute, FnAttribute.DataAttribute):
            typeName = None
            if isinstance(attribute, FnAttribute.IntAttribute):
                typeName = "IntAttr"
            elif isinstance(attribute, FnAttribute.FloatAttribute):
                typeName = "FloatAttr"
            elif isinstance(attribute, FnAttribute.DoubleAttribute):
                typeName = "DoubleAttr"
            elif isinstance(attribute, FnAttribute.StringAttribute):
                typeName = "StringAttr"

            if typeName is not None:
                result["type"] = typeName

                # Only add if not the default.
                if attribute.getTupleSize() != 1:
                    result["tupleSize"] = attribute.getTupleSize()

                # If only one value, just add it as a scalar. Also, if only
                # samples at 0.0 are available, don't add times: it helps
                # readability.
                samples = attribute.getSamples()
                if len(samples) == 1 and list(samples.keys())[0] == 0.0:
                    values = samples[0.0]
                    if len(values) == 1:
                        result["value"] = values[0]
                    else:
                        result["values"] = list(values)
                else:
                    result["samples"] = {}
                    for timeSample, values in samples.items():
                        if len(values) == 1:
                            result["samples"][str(timeSample)] = values[0]
                        else:
                            result["samples"][str(timeSample)] = list(values)
        elif isinstance(attribute, FnAttribute.GroupAttribute):
            result["type"] = "GroupAttr"

            # Only add if not the default.
            if not attribute.getGroupInherit():
                result["groupInherit"] = False

            # Recursively call this function to write the attributes for its
            # children
            children = {}
            for childName, childAttribute in attribute.childList():
                children[childName] = JsonLookFileBakeOutputFormat.attrToDict(
                    childAttribute)
            result["children"] = children

        return result

# Register the output format.
LookFileBakeAPI.RegisterOutputFormat(JsonLookFileBakeOutputFormat)

LookFileBake API

This module contains the LookFileBakeAPI moved over from PyUtil. It contains the OutputFormatAPI (Which was formerly the LookFileBakeAPI), which allows users to register their own Look File Bake output format.

It also contains the constants defined from the Nodes3DAPI.LookFileConstants module.

We expose both of these here as not to change the imports required for the LookFileBakeAPI.

class LookFileBakeAPI.BakePrePostHandlerBase

Bases: object

Base class for Pre/Post Look File bake callback handlers.

Since:

Katana 4.0v1

notify(assetId, rootLocationProducers, progressCallback, abortCallback)

Handles a Pre/Post Look File bake notification.

Parameters:
  • assetId (str) – Look File Asset ID

  • rootLocationProducers (dict of str to FnGeolibProducers.GeometryProducer) – Dictionary of Geometry Producers keyed on root location path.

  • progressCallback (callable or None) – Optional callback that may be called with a single string argument providing the current baking status.

  • abortCallback (callable or None) – Optional callback that may be called to abort the bake, with a single string argument providing a reason.

class LookFileBakeAPI.BaseLookFileBakeOutputFormat(settings)

Bases: object

Base class representing a LookFileBake output format. Users wishing to define their own format for Look File baking should inherit from this class and overwrite the provided class variables and instance methods.

Variables:
  • DisplayName – The name used in the Parameters tab UI to identify the output format.

  • FileExtension – The extension of top level file generated by the output format. For output formats which write passes into a directory, it should be an empty string. This is not appended to the file path value in pass data of writeSinglePass(), see PassFileExtension.

  • PassFileExtension – The extension of the individual pass files generated by the output format. This is used for creating the file path provided to pass data in writeSinglePass().

  • Hidden – ✨ New in Katana 4: Flag which excludes this Output Format plug-in from OutputFormatAPI listing methods by default.

DisplayName = None
FileExtension = None
Hidden = False
PassFileExtension = None
__init__(settings)

Initializes an instance of the class with the given settings.

Parameters:

settings (LookFileBakeSettings) – The LookFileBake settings with which to initialise the output format.

postProcess(filePaths)

Performs any post-processing that might be needed after a set of passes have been written.

Return type:

list of str

Parameters:

filePaths (list of str) – A list of files which have been written so far.

Returns:

A list containing any files created by the post-process. The default implementation simply returns filePaths.

writeSinglePass(passData)

Writes a single Look File pass using the current settings and the given pass data.

Return type:

list of str

Parameters:

passData (LookFilePassData) – The data representing a single Look File pass to be baked.

Returns:

A list of paths to files which have been written. The default implementation returns an empty list.

LookFileBakeAPI.CreateLookFileDirectory(dirPath)

Utility function to create and check writeability of a directory path.

Parameters:

dirPath (str) – The path to the directory to create if required.

Raises:

LookFileBakeException – If the directory couldn’t be created or isn’t writeable.

LookFileBakeAPI.GetDefaultOutputFormat()
Return type:

BaseLookFileBakeOutputFormat or None

Returns:

The default LookFileBake output format, or None if no valid output format has been set.

LookFileBakeAPI.GetOutputFormatByName(outputFormatName)
Return type:

BaseLookFileBakeOutputFormat

Parameters:

outputFormatName (str) – The name of the output format to return.

Returns:

The output format registered with the given name.

Raises:

ValueError – If there is no output format registered with the given name.

LookFileBakeAPI.GetOutputFormatFileExtensions(includeHidden=False)
Parameters:

includeHidden (bool) – Option to include output formats whose Hidden property is set to True.

Return type:

list of str

Returns:

A list of file extensions for the registered output formats.

LookFileBakeAPI.GetOutputFormatNames(includeHidden=False)
Parameters:

includeHidden (bool) – Option to include output formats whose Hidden property is set to True.

Return type:

list of str

Returns:

A list of the names of the registered output formats.

LookFileBakeAPI.GetOutputFormats(includeHidden=False)
Parameters:

includeHidden (bool) – Option to include output formats whose Hidden property is set to True.

Return type:

list of BaseLookFileBakeOutputFormat

Returns:

A list of the registered output formats.

class LookFileBakeAPI.LocationIntervalEvictor(interval=0)

Bases: TraversalObserverBase

A traversal observer that evicts Geolib runtime scene data after traversing a specified number of scene graph locations.

__init__(interval=0)

Initializes with the specified eviction interval.

Parameters:

interval (int) – Eviction interval (number of locationa traversed)

advance(producer)

Handles traversal to the scene graph location of the given Geometry Producer.

Evicts the primary Geolib Runtime instance’s scene data after every [interval] calls to this function.

Parameters:

producer (FnGeolibProducers.GeometryProducer) – Geometry Producer for the scene graph location that is being visited (is about to be processed).

reset()

Resets this instance for a new traversal by resetting its traversal counter.

exception LookFileBakeAPI.LookFileBakeException

Bases: RuntimeError

Raised when an error occurs during a Look File baking process.

class LookFileBakeAPI.LookFileBakeSettings(settings=None)

Bases: _BaseSettings

Class representing settings for a Look File bake action.

The following settings are contained in this class:

  • outputPath - The path selected by the user to write to. This can be a file or a directory, depending on the output format plug-in doing the writing.

  • outputFormatName - The name of the output format plug-in doing the writing. This can be passed to GetOutputFormatByName to obtain the registered plug-in class. This name is the same as the BaseLookFileBakeOutputFormat.DisplayName class variable defined by output format plug-ins.

  • sourceFile - The path to the Katana file from which baking is taking place.

  • sourceAsset - The asset ID of the Katana file from which baking is taking place.

__init__(settings=None)

Initializes an instance of the class with the given settings.

Parameters:

settings (dict or None) – The settings to store in this instance.

class LookFileBakeAPI.LookFileBaker(outputFormatName)

Bases: object

Class holding properties and functionality for baking Look Files.

Since:

Katana 4.0v1

__init__(outputFormatName)

Initializes a default LookFileBaker for the specified Output Format.

Parameters:

outputFormatName (str) – The name of the output format to use when writing the baked scene difference. This should match a registered LookFileBakeOutputFormat plugin.

property additionalSettings

Additional settings (dict) that are passed to the Output Format Plug-in as part of LookFileBakeSettings. This data is shared between each writeSinglePass() call. These settings cannot override core settings.

bake(referenceOp, passNamesAndOps, rootLocations, outputPath)

Bakes scene graph differences to a Look File.

Return type:

list of str

Parameters:
  • referenceOp (PyFnGeolib.GeolibRuntime.Op) – An Op that produces the reference scene graph.

  • passNamesAndOps (iterable of (str, PyFnGeolib.GeolibRuntime.Op) pairs) – Pass names and the Ops that produce their scene graphs.

  • rootLocations (iterable of str) – Root locations of the scene graph branches whose differences are to be written.

  • outputPath (c{str}) – The output path.

Returns:

List of written file paths.

Raises:

LookFileBakeException – On arbitrary failure, including an abort issued by a callback.

Note:

Ops provided to this function are expected to be configured as being part of an active bake: LookFileResolve Ops preserve look file references when provided the ‘activeBake’ Op arg as an IntAttribute of value ‘1’.

Note:

The LookFileBakeAPI.LookFilePassData ‘filePath’ entry is populated as an os.path.join() of outputPath and a pass-specific output file name. However it is not intended that outputPath necessarily be limited to directory paths. Pass data may change in future versions of Katana to provide a clearer workflow.

bakeAndPublish(referenceOp, passNamesAndOps, rootLocations, assetId, assetArgs=None, preBakeHandler=None, postBakeHandler=None)

Bakes scene graph differences to a Look File and publishes it as a Look File asset.

Checks rootLocations using LookFileBakeAPI.Utils.CheckRootLocations(), and writes the created Look File asset to disk using bake().

Return type:

str

Parameters:
  • referenceOp (PyFnGeolib.GeolibRuntime.Op) – An Op that produces the reference scene graph.

  • passNamesAndOps (iterable of (str, PyFnGeolib.GeolibRuntime.Op) pairs) – Pass names and the Ops that produce their scene graphs.

  • rootLocations (iterable of str) – Root locations of the scene graph branches whose differences are to be written.

  • assetId (str) – The asset ID to which to write the Look File. This is resolved using the Default Asset Plugin from the AssetAPI.

  • assetArgs (dict or None) – Any additional args to be passed to the Asset Plugin’s createAssetAndPath method. This is extended with ‘outputFormat’ from outputFormatName.

  • preBakeHandler (BakePrePostHandlerBase or None) – Handler for the ‘pre-bake’ notification.

  • postBakeHandler (BakePrePostHandlerBase or None) – Handler for the ‘post-bake’ notification.

Returns:

The canonical asset ID of the asset written, which may have been modified by the asset plug-in (e.g. forcing filenames to have appropriate extensions), as part of the Asset plug-ins createAssetAndPath and postCreateAsset methods.

Raises:

LookFileBakeException – On arbitrary failure, including an abort issued by a callback.

Note:

Ops provided to this function are expected to be configured as being part of an active bake: LookFileResolve Ops preserve look file references when provided the ‘activeBake’ Op arg as an IntAttribute of value ‘1’.

property includeGlobalAttributes

A flag (bool) indicating whether global attributes should be included.

property includeLodInfo

A flag (bool) indicating whether level-of-detail information should be included.

property materialTreeRootLocations

A list of material root locations (list of str, or None) to write out as complete scene graph for each pass (as opposed to as diffs against the reference scene).

property outputFormatName

The name (str) of the output format to use when writing the baked scene difference. This should match a registered LookFileBakeOutputFormat plugin.

property progressCallback

An optional callback (callable or None) that is called with a single string argument providing the current baking status.

property sourceAsset

An optional source asset ID (str or None).

property sourceFile

An optional source file path (str or None).

property traversalObserver

An optional traversal observer (TraversalObserverBase or None) that is notified when traversing each scene graph location during a diff operation. This may perform actions such as periodically evicting Geolib runtime scene data (see LocationIntervalEvictor). The observer is reset using its reset() method prior to scene traversal.

class LookFileBakeAPI.LookFilePassData(settings=None)

Bases: _BaseSettings

Class encapsulating the data for a single Look File pass baking action.

The following settings are contained in this class:

  • filePath - The path to the file to which data should be written for this pass. This may be a path to a file inside the directory selected by the user, or a path to a temporary file which will be copied or archived to the final user-selected location.

  • passName - The name of the pass which is being baked. This corresponds to the name of the input port on the LookFileBake node from which the bake was initiated.

  • outputDictList - A list of tuple`s, where each entry is of the form :py:obj:`(overrideDict, rootName, rootType).

    • overrideDict - A dictionary mapping baked locations to opaque identifiers, which are used as keys into sharedOverridesDict, specifying attribute overrides for the location.

    • rootName - The name of the root location being baked.

    • rootType - The type of the root location being baked.

  • materialDict - A dictionary mapping material location paths to a tuple of (locationType, attribute).

    • locationType is the type of the location (usually 'material')

    • attribute is a FnAttribute describing the material attribute.

  • sharedOverridesDict - A dictionary mapping the opaque identifiers (referenced by the entries in overrideDict, described above) to a dictionary mapping names of attributes to FnAttribute instances providing the attribute values.

  • rootOverrideDict - A dictionary providing attribute overrides at /root, mapping attribute names to FnAttribute instances providing the attribute values. This is only generated if the includeGlobalAttributes parameter on the LookFileBake node is enabled.

__init__(settings=None)

Initializes an instance of the class with the given settings.

Parameters:

settings (dict or None) – The settings to store in this instance.

class LookFileBakeAPI.OutputFormat

Bases: object

Enumeration definining possible options the outputFormat parameter of LookFileBake nodes.

AS_ARCHIVE = 'as archive'
AS_DIRECTORY = 'as directory'
DEFAULT = 'as archive'
LookFileBakeAPI.RegisterOutputFormat(outputFormat)

Registers a new output format for Look File baking.

Parameters:

outputFormat (BaseLookFileBakeOutputFormat) – The output format to register.

Raises:

ValueError – If the display name of the output format is already in use by other previously registered output format.

LookFileBakeAPI.SetDefaultOutputFormat(outputFormat)
Parameters:

outputFormat (BaseLookFileBakeOutputFormat) – The output format to set as the default.

class LookFileBakeAPI.TraversalObserverBase

Bases: object

A traversal observer that is notified when traversing each scene graph location during a diff operation. This may perform actions such as periodically evicting Geolib runtime scene data (see LocationIntervalEvictor). The observer is reset using its reset() method prior to scene traversal.

advance(producer)

Handles traversal to the scene graph location of the given Geometry Producer.

Parameters:

producer (FnGeolibProducers.GeometryProducer) – Geometry Producer for the scene graph location that is being visited (is about to be processed).

reset()

Resets this instance for a new traversal.

LookFileBakeAPI.UnregisterOutputFormat(outputFormat)

Unregisters an output format.

Parameters:

outputFormat (BaseLookFileBakeOutputFormat or str) – The output format, or the display name of the output format to be unregistered.

Raises:

ValueError – If the output format cannot be unregistered.