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.
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 valuedefault: the fallback/default valueenable: 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.
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.
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
defaultvalue.The
Parametergetter for.valuereturns the stored current value.The
ParameterPolicygetter 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:
Resolve the target parameter from the node.
Create a policy with
UI4.FormMaster.CreateParameterPolicy(parentPolicy, param).Build the widget with
UI4.FormMaster.ParameterWidgetFactory.buildWidget(parentWidget, policy).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
NoneasparentPolicy.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:
After registering the EnableableScalarParameterPolicyDelegate, the ImageCoordinate node
displays enable/disable buttons to the left of each parameter:
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 |
|
Expressions, curves, states, validation |
ArrayParameterPolicy |
|
Dynamic sizing, child management |
GroupParameterPolicy |
|
Child policy management, hierarchy |
CurveParameterPolicy |
|
Curve editing, keyframe management |
OpaqueParameterPolicy |
|
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 |
|
EnableableScalarParameterPolicy |
Parameters with enable/disable functionality |
Enableable |
|
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 |
|
StageParameterPolicy |
USD stage parameter handling |
Enableable and return existing attribute value as a default value |
|
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>