Parameter Policy

Introduction

Parameter Policies in Katana are value policies that provide a layer in between parameters of nodes in the node graph document and widgets in the Parameters tab. Those widgets show values of parameters, and can be used to edit those parameter values.

Katana User Guide Glossary

This document explains the difference between Parameter and Parameter Policy accesses, the basics of how to use them through practical code examples, and existing policy types.

Warning

Parameter Policies only support existing UI widgets and existing parameter types.

Parameter vs Policy Value Access

While parameters serve as data storage, they do not necessarily return values as they appear in the UI. For example, when a parameter has a default value, the UI uses a parameter policy to display either the default value or the override value, depending on the state of the enable parameter that controls whether the override is active. Similarly, when you modify a value through the UI, it automatically updates the enable parameter. However, when you directly modify a parameter programmatically, the enable parameter is not automatically updated. Accessing parameters through parameter policies allows you to read and write values in a way that is consistent with UI behavior.

Abstractly, the difference between Parameter and Parameter Policy access can be summarized as follows:

Parameter:

  • Best for direct data reads/writes without UI condition.

  • Reads raw stored values from specific parameter paths.

  • For example, reading and writing many parameters in a batch process.

Parameter Policy:

  • Best for UI-facing tools and editor workflows.

  • Reads and writes values in a way that follows policy/UI state handling.

  • For example, reading parameters as they appear in the UI using simple code.

This section explains how to access Parameters correctly and compares two approaches for cameraName on a RenderSettings node:

The examples show how each approach reads and writes values, and clarify when policy-based access is the safer choice for keeping UI-related parameter state consistent.

1) Set a value via Parameter

In this case, cameraName is represented as a parameter group with three child parameters:

  • value: the current value

  • default: the fallback/default value

  • enable: whether the override is active

Initially, default matches value, and enable is 0. Setting only value does not automatically switch enable to 1.

from Katana import NodegraphAPI

rootNode = NodegraphAPI.GetRootNode()
node = NodegraphAPI.CreateNode("RenderSettings", rootNode)
camera_param_value = node.getParameter("args.renderSettings.cameraName.value")

# Write to Parameter
camera_param_value.setValue("/root/world/cam/mainCam", 0)

The parameter is not enabled yet, so the UI still shows the default value, and the override value is not applied in the scene. This is because the enable parameter is still 0.

../../_images/ParameterPolicy_parameter_setValue.png

To apply the override, you need to set enable to 1 as well.

camera_param_enable = node.getParameter("args.renderSettings.cameraName.enable")
camera_param_enable.setValue(1, 0)

2) Set a value via Parameter Policy

With policy-based access, you do not need to handle enable manually. The policy handles the state transition and sets enable to 1 automatically when the value is updated.

 from Katana import NodegraphAPI, UI4

 rootNode = NodegraphAPI.GetRootNode()
 node = NodegraphAPI.CreateNode("RenderSettings", rootNode)
 camera_param = node.getParameter("args.renderSettings.cameraName")
 policy = UI4.FormMaster.CreateParameterPolicy(None, camera_param)

# Write through Policy
policy.setValue("/root/world/cam/mainCam")

The parameter is enabled and the override value is applied in the scene immediately after setting the value through the policy, without needing to set enable explicitly.

../../_images/ParameterPolicy_policy_setValue.png

3) Get a value via Parameter and Parameter Policy

Getting values can also produce different behavior between Parameter and ParameterPolicy.

When enable is False:

  • The UI displays the default value.

  • The Parameter getter for .value returns the stored current value.

  • The ParameterPolicy getter returns the value that is currently displayed in the UI (the default value in this state).

from Katana import NodegraphAPI, UI4

rootNode = NodegraphAPI.GetRootNode()
node = NodegraphAPI.CreateNode("RenderSettings", rootNode)

camera_group_param = node.getParameter("args.renderSettings.cameraName")
camera_value_param = node.getParameter("args.renderSettings.cameraName.value")
camera_enable_param = node.getParameter("args.renderSettings.cameraName.enable")

# Prepare a state where UI should display default.
camera_value_param.setValue("/root/world/cam/currentCam", 0)
camera_enable_param.setValue(False, 0)

# Raw parameter getter reads the stored current value.
value_from_param = camera_value_param.getValue(0)

# Policy getter reads the effective/displayed value.
policy = UI4.FormMaster.CreateParameterPolicy(None, camera_group_param)
value_from_policy = policy.getValue()

# Expected result:
# value_from_param  == "/root/world/cam/currentCam"
# value_from_policy == "/root/world/cam/camera"

Using Parameter Policy

Basic Parameter Policy Creation

Parameter policies are created through the FormMaster.CreateParameterPolicy function, which automatically selects the appropriate policy type based on the parameter type and node type. The system uses a delegate pattern where different node types can register custom policy delegates to override default behavior.

from UI4.FormMaster import CreateParameterPolicy
import NodegraphAPI

# Get a parameter from a node
node = NodegraphAPI.GetNode('myNode')
param = node.getParameter('myParam')

# Create a parameter policy
policy = CreateParameterPolicy(None, param)  # None = root policy

if policy:
    # Policy created successfully
    print(f"Created {policy.getType()} policy for {param.getName()}")

Hierarchical Policy Creation

When creating policies in a hierarchy, a parent policy can be passed into CreateParameterPolicy(parentPolicy, param). This links the child policy to its parent and allows the parent policy to manage child policy behavior consistently.

Some policy types require specific child parameters such as enable and value. In most cases, these essential children are handled by the policy creation function, so you do not need to create them manually.

# Create parent policy first
parentParam = node.getParameter('parentGroup')
parentPolicy = CreateParameterPolicy(None, parentParam)

# Create child policies with parent reference
childParam = parentParam.getChild('childParam')
childPolicy = CreateParameterPolicy(parentPolicy, childParam)

# Parent automatically manages child policies for groups
children = parentPolicy.getChildren()

Building a Widget from a Parameter Policy

Use this workflow when you want to add existing parameter widgets to your own custom UI, such as a custom editor in a SuperTool, while keeping Katana’s standard parameter UI behavior.

Before creating a widget from a policy, you can also update the policy’s widget hints. This lets you customize how the parameter appears in the UI, such as changing the displayed label. It is useful when building your own tools in Katana, for example a custom panel or SuperTool editor. The available hints depend on the parameters and the types of widgets. For more details, see Widgets and Hints.

Implementation steps:

  1. Resolve the target parameter from the node.

  2. Create a policy with UI4.FormMaster.CreateParameterPolicy(parentPolicy, param).

  3. Build the widget with UI4.FormMaster.ParameterWidgetFactory.buildWidget(parentWidget, policy).

  4. Return the created widget to the caller.

from Katana import NodegraphAPI, UI4

def create_parameter_widget(node_name, parameter_path, parent_widget=None):
    """Create and return a widget for a Katana parameter."""
    node = NodegraphAPI.GetNode(node_name)
    param = node.getParameter(parameter_path)

    # Root policy creation: parentPolicy is None.
    policy = UI4.FormMaster.CreateParameterPolicy(None, param)

    # Update hints before creating the widget.
    hints = policy.getWidgetHints()
    hints["label"] = "Primary Camera"

    return UI4.FormMaster.ParameterWidgetFactory.buildWidget(parent_widget, policy)

def build_editor(parent=None):
    return create_parameter_widget("myNode", "myGroup.myParam", parent)

Developer notes:

  • For a root parameter, pass None as parentPolicy.

  • If no widget appears, verify that the node and parameter path are valid and that policy creation did not return None.

Policy Delegate Registration

Parameter policy delegates are registered using the RegisterPolicyDelegate function to provide custom policy behavior for specific node types. This allows you to define how policies are created for parameters of those nodes, enabling specialized handling of the UI and its behavior.

For example, you can register EnableableScalarParameterPolicyDelegate for the example SuperTool ImageCoordinate node by uncommenting the relevant code within:

$KATANA_ROOT/plugins/Src/Resources/Examples/SuperTools/ImageCoordinate/v1/__init__.py

By default, the ImageCoordinate node does not display enable/disable buttons:

../../_images/ParameterPolicy_default_ImageCoordinate.png

After registering the EnableableScalarParameterPolicyDelegate, the ImageCoordinate node displays enable/disable buttons to the left of each parameter:

../../_images/ParameterPolicy_enableable_ImageCoordinate.png

If you want to further customize the policy creation, you can create your own delegate class by inheriting from ParameterPolicy.ParameterPolicyDelegate and implementing the createPolicy method. Then, register your custom delegate for the target node type.

from UI4.FormMaster import ParameterPolicy

# Register a custom delegate for a specific node type
ParameterPolicy.RegisterPolicyDelegate('MyNodeType', MyCustomDelegate())

Custom delegates must implement the createPolicy method:

class MyCustomDelegate(ParameterPolicy.ParameterPolicyDelegate):
    def createPolicy(self, parentPolicy, param):
        # Custom policy creation logic
        if param.getType() == 'string' and param.getName() == 'customParam':
            return MyCustomParameterPolicy(param, parentPolicy)

        # Fall back to default behavior
        return ParameterPolicy.ParameterPolicyDelegate.createPolicy(
            self, parentPolicy, param)

Parameter Policy Types

Core Parameter Policy Types

The following table shows the built-in parameter policy types and their use cases:

Policy Type

Parameter Types

Features

ScalarParameterPolicy

number, string

Expressions, curves, states, validation

ArrayParameterPolicy

numberArray, stringArray

Dynamic sizing, child management

GroupParameterPolicy

group, dynamicgroup

Child policy management, hierarchy

CurveParameterPolicy

curve

Curve editing, keyframe management

OpaqueParameterPolicy

opaque

Binary data handling

Specialized Parameter Policy Types

Beyond the core types, Katana provides several specialized parameter policy types for specific use cases. This list represents only some of the policies currently used in Katana.

Policy Type

Purpose

Features

Example

DefaultableParameterPolicy

Parameters with default value override

Defaultable and enableable

properties.size on UsdCubeCreate node

EnableableScalarParameterPolicy

Parameters with enable/disable functionality

Enableable

projection on CameraCreate node

EnableableGroupParameterPolicy

Groups with enable/disable functionality

Enableable and has child policy as group

Not used in current Katana version

GraphStateVariableValuePolicy

Graph state variable handling

Defaultable and enableable

variables.var1 on root node

StageParameterPolicy

USD stage parameter handling

Enableable and return existing attribute value as a default value

properties.inputs.diffuse on UsdLight node

DefaultableParameterPolicy

Parameter XML structure:

<group_parameter hints="{}" name="size">
  <number_parameter name="enable" value="0"/>
  <number_parameter name="value" value="2"/>
  <number_parameter name="default" value="2"/>
</group_parameter>

EnableableScalarParameterPolicy

Parameter XML structure:

<string_parameter name="projection" value="perspective"/>

GraphStateVariableValuePolicy

Parameter XML structure:

<group_parameter name="var1">
  <number_parameter name="enable" value="0"/>
  <string_parameter name="value" value=""/>
</group_parameter>

StageParameterPolicy

Parameter XML structure:

<group_parameter hints="{}" name="diffuse">
  <number_parameter name="enable" value="0"/>
  <number_parameter name="stageparameter" value="0"/>
  <string_parameter name="propertyType" value="attribute"/>
  <number_parameter name="value" value="1"/>
  <number_parameter name="default" value="1"/>
</group_parameter>