Katana uses the KATANA_RESOURCES environment variable to provide a list of paths under which to look for plug-ins and other customizations (such as shelves, tabs, and resolutions). This can also be a list of directories, separated by a colon (if you're on Linux) or a semi-colon (if you're on Windows ). The idea is to allow you to build up a list of resource locations. If you’re a developer writing plug-ins for Katana, you need to make sure they go in the right place in order for them to be picked up properly.
Examples are provided in the following directory, and are loaded if this path is included in the KATANA_RESOURCES environment variable:
Adding New Paths
Any directories you add to the KATANA_RESOURCES path are searched by Katana for plug-in. For example, you could specify:
You should then see the following when Katana starts:
> katana [INFO LicenseCheck]: Interactive License OK [INFO python.ResourceFiles]: Additional Katana resource paths from $KATANA_RESOURCES: [INFO python.ResourceFiles]: /home/tom/dev/katana/Resources [INFO python.ResourceFiles]: /tools/site/katana/Resources
These are searched in addition to those listed in the Defaults section, discussed in more detail below.
Note: The $KATANA_RESOURCES variable behaves as a standard Linux environment variable. Consequently, if you wish to append a directory to this, keeping anything that is already there, you have to take care of when editing this.
The paths that you place on KATANA_RESOURCES are not actually searched directly. Instead, there is a meaningful set of sub-directories that are used by different parts of the program. For Python modules, the ‘types’ listed refer to the first value of each tuple set in the module’s PluginRegistry list.
• Args - the .args files for shaders.
• AssetPlugins - Python-based AssetPlugin and FileSequencePlugin plug-ins.
Note: As of 3.0v1, Python-based AssetAPI plug-ins have been deprecated. Support for them has been removed when Katana transitioned from Python 2.7 to Python 3.7 as part of moving to VFX Reference Platform CY2020.
• Gaffer* - Python-based GafferModule plug-ins (Script Items) that extend the Gaffer super tool.
Note: The classic Gaffer node type is deprecated and has been replaced with GafferThree. (Custom packages for GafferThree can be created using PackageSuperToolAPI.)
• GenericAssign - templates for defining new GenericAssign-based nodes (.xml).
• Importomatic* - Python-based ImportomaticModule plug-ins that form plug-ins for the Importomatic SuperTool.
• Layouts - creating a directory called Layouts in your KATANA_RESOURCES path allows you to load layouts from files named KatanaLayout2.xml or other files ending in .katanalayout.xml. For example:
Layouts saved from Katana's Layouts menu are still saved in the KatanaLayout2.xml file in the current user's .katana resource directory in the OS home directory. For example:
• Windows: C:\Users\<login name>\.katana
• Linux: /home/<login name>/.katana
• Libs - any compiled C++ plug-ins for Katana, for any API; for example, C-based asset plug-ins (.so).
• Macros - nodes saved as macros from the Katana UI (.macro).
• Ops - C++ plug-ins that can arbitrarily create and manipulate scene data. Ops can also be placed in the Libs sub-folder within KATANA_RESOURCES. The Ops are loaded in Katana regardless of whether they are placed in the Libs or Ops folders.
• Plugins - sundry Python modules, including types such as GafferProfile, KatanaPlugin, RenderLocationPlugin, ViewerProxyLoader, UVTileFormats.
• RenderBin - this directory isn’t actually a standard Katana directory, but many render plug-ins use this to store binaries and plug-ins that are loaded by the renders themselves to talk to Katana.
• Resolutions - additional resolution files (.xml).
• Shaders - any additional shaders for a renderer. The only time this directory is considered by Katana itself is to locate shaders for the viewer (.glsl).
• Shelves - a directory for each shelf, containing Python scripts for each shelf item.
• Startup - Python scripts that can be used to configure Katana at startup. The only file that is explicitly run (with execfile) is one called init.py. If you wish to run other scripts or import modules, they would need to be called from there.
• SuperTools* - Python modules that implement new SuperTools.
• Tabs* - Python modules (KatanaPanel) that implement new tabs that can be docked to panes in the UI.
• UIPlugins - Python modules that implement UI-specific plug-ins, such as AssetWidgetDelegates and KatanaPlugin.
Note: These plug-ins aren't loaded in --batch, --script, and --shell launch modes.
• ViewerManipulators - additional Python manipulators (KatanaManipulator) for the viewer.
Katana always looks in the following (internal) places, regardless of what you set KATANA_RESOURCES to. $KATANA_ROOT is where the Katana installation lives.
Generally, the search order is by ‘standard path behavior’. Namely, Katana looks at the directories, left to right. What you may observe, though, differs a little depending on the type of plugin/directory being loaded.
Many of the compiled plug-ins work on the basis that the ‘first one loaded’ sticks. This is not based on the .so name, but instead the name passed to the REGISTER_PLUGIN. Repeat registrations with the same name are ignored. The plug-ins in each directory are iterated by readdir so are loaded in ‘filesystem order’.
In the case of ViewerModifierPlugins, where the mapping is to a location type (based on an API call), the effective winner for any location is the first named registration that accepts to a particular location type.
But what is the ‘first’ plug-in? In the case of multiple registrations of the same name, for example, a local build of a central plug-in, both named ‘OuModifier’, you get the first on the path from left to right. However, when multiple, independently-named registrations handle the same type, for example, 'LightModifier’ and ‘MyLightModifier’, you end up with the first one iterated from the internal plug-in map, which presently ends up being ordered alphabetically.
Python modules are generally sourced from directories (using __import__), from left to right. So, the first module that registers a specific name in its PluginRegistry wins. Within any directory, plug-ins are loaded by os.listdir, which documents its ordering as arbitrary. However, some code reverses this search order. Any directories listed with an asterisk (*) above are right-to-left precedence. Additionally, shelves don't work quite as you might expect, as the shelf mechanism searches left-to-right (non-reversed). This means that the right-most files contents win out.