Creating Custom Templates
To this point, we have explored how to extend and customize the template applications and extensions provided by the kit-app-template
repository. In this section, we will explore how to create a custom template using the provided tooling. This process will allow you to create a new application or extension template that can be used as a starting point for new projects withing your team or organization.
Template Configuration
The repo template
uses the templates/templates.toml
configuration file to define the available templates and their properties. The templates.toml
file is structured as follows:
[templates."template_name"]
class = "ApplicationTemplate" or "ExtensionTemplate"
name = "Template Display Name"
url = "location of template, '.' for local"
subpath = "path/to/the/template/at/specified/url"
variables.first_variable = "the first variable to be queried from the user"
variables.second_variable = "the second variable to be queried from the user"
...
variables.nth_variable = "the nth variable to be queried from the user"
[templates."template_name".extensions]
template = "ExtensionTemplate"
type = "extension type"
Configuration Examples
The following examples demonstrate how to configure a custom application and extension template using the templates.toml
configuration file. In the examples below we show the configuration for the kit_service
application template and the corresponding kit_service_setup
setup extension template.
Application Template Configuration
[templates."kit_service"]
class = "ApplicationTemplate"
name = "Kit Service"
url = "."
subpath = "apps/kit_service/kit_service.kit"
variables.application_name = "my_company.my_service"
variables.application_display_name = "My Service"
variables.version = "0.1.0"
[[templates."kit_service".extensions]]
template = "kit_service_setup"
type = "setup"
Extension Template Configuration
[templates."kit_service_setup"]
class = "SetupExtensionTemplate"
name = "Service Setup"
url = "."
subpath = "extensions/service.setup/template"
variables.extension_name = "my_company.my_service_setup_extension"
variables.extension_display_name = "My Service Setup Extension"
variables.version = "0.1.0"
Default Behaviors
There are some default behaviors that are applied to all templates. These behaviors include:
application_name and extension_name: These variables are required for all templates and will always be the first variables queried from the user. It is recommended that the default value for these variables is set as the first variable listed in the
templates.toml
configuration for a given template.Variables in Order: The variables are queried from the user in the order they are listed in the
templates.toml
configuration file. It is recommended that theapplication_name
andextension_name
variables are listed first.Found Variables: While it is recommended to set all critical defaults using the variables listed in the
templates.toml
configuration file, users will be prompted for all variables that are found in the template files themselves in the order they are found. Variables set within the template files can be set with the pattern{{variable_name}}
and will be replaced with the user input. If you wish to set a default value within the template file, you can use the pattern{{variable_name|default('default_value')}}
.Multiple Application Extensions: In the above example we show how to configure a single setup extension for the
kit_service
. If you wish to add multiple extensions to an application, you can add additional[[templates."app_name".extensions]]
entries to thetemplates.toml
configuration file along with the relevant extension template configuration. Each entry should specify thetemplate
andtype
of the extension. Note that each extension that is required to be added to the.kit
file will require an entry of the form"{{ extension-type_extension_name }}" = {}
in the.kit
file.Multiple Application Extensions (Dependencies): For extensions that depend on one another, it is recommended to list them in the
templates.toml
file in the order from least dependent to most dependent (e.g. if extension A depends on extension B, list extension B first). This will limit the number of times the user is prompted for variables. An example of this can be seen with theomni_usd_viewer
application template. Note that when one extension depends on another, only the top level extension needs to be added to the.kit
file.Application Template Layering: Application templates can depend on each other. When configuring template layers using the
templates.toml
file, theApplicationLayerTemplate
class is used. This approach is particularly useful when you want to inherit the behavior of a base application and extend it with additional functionality, such as streaming.
Hands-on Exploration
In this section we will create a template extension that builds upon the Python UI extension template. Our goal will be to create a simple UI element that launches a Warp kernel. Warp is a Python framework for writing high-performance simulation and graphics code. Warp takes regular Python functions and JIT compiles them to efficient kernel code that can run on the CPU or GPU. Our new template will allow our users to quickly setup a new Warp kernel and launch it from within the Omniverse Kit UI.
1. Create a New Template Extension
Within the
templates/extensions
directory, create a new directory calledwarp_kernel_ui
for the new template extension.From within the
templates/extensions/python_ui
directory, copy the entiretemplate
directory to the newwarp_kernel_ui
directory.Our new directory within the
templates/extensions
directory should look like this:warp_kernel_ui/ ├── template/
Update the
[dependencies]
section of theextension.toml
file within thetemplates/extensions/warp_kernel_ui/template/config
directory to the following :[dependencies] "omni.kit.uiapp" = {} "omni.warp" = {} # Warp support
Update the python code contained within
templates/extensions/warp_kernel_ui/template/{{python_module_path}}/extension.py
to the following code:
import omni.ext
import omni.ui as ui
import warp as wp
import numpy as np
# Warp kernel to computes the lengths of 3D vectors
@wp.kernel
def length(points: wp.array(dtype=wp.vec3),
lengths: wp.array(dtype=float)):
# thread index
tid = wp.tid()
# compute distance of each point from origin
lengths[tid] = wp.length(points[tid])
# Any class derived from `omni.ext.IExt` in the top level module (defined in `python.modules` of `extension.toml`) will
# be instantiated when the extension gets enabled, and `on_startup(ext_id)` will be called.
# Later when the extension gets disabled on_shutdown() is called.
class MyExtension(omni.ext.IExt):
# ext_id is the current extension id. It can be used with the extension manager to query additional information,
# like where this extension is located on the filesystem.
def on_startup(self, ext_id):
print("[{{ extension_name }}] Extension startup")
wp.init()
self._count = 0
self._num_points = 1024
self._window = ui.Window("{{ extension_display_name }}", width=300, height=300)
with self._window.frame:
with ui.VStack():
label = ui.Label("")
def on_click():
self._count += 1
label.text = f"# Runs: {self._count}"
# allocate an array of 3d points
points = wp.array(np.random.rand(self._num_points, 3), dtype=wp.vec3)
lengths = wp.zeros(self._num_points, dtype=float)
# launch kernel
wp.launch(kernel=length,
dim=len(points),
inputs=[points, lengths])
print(lengths)
with ui.HStack():
ui.Button("Run Kernel", clicked_fn=on_click)
def on_shutdown(self):
print("[{{ extension_name }}] Extension shutdown")
2. Configure the New Template Extension
Add the following entry to the templates/templates.toml
file to configure the new template extension:
[templates."warp_kernel_ui"]
class = "ExtensionTemplate"
name = "Warp Kernel UI"
url = "."
subpath = "extensions/warp_kernel_ui/template"
variables.extension_name = "my_company.warp_kernel_ui"
variables.extension_display_name = "Warp Kernel UI"
variables.version = "0.1.0"
3. Test the New Template Extension
To test the new template extension we will create a Base Editor application and include the new Warp Kernel UI extension.
Create a new Base Editor application using the
repo template new
command:Linux:
./repo.sh template new
Windows:
.\repo.bat template new
Follow the prompt instructions, choosing:
? Select with arrow keys what you want to create: Application
? Select with arrow keys your desired template: Kit Base Editor
? Enter name of application .kit file [name-spaced, lowercase, alphanumeric]: my_company.my_editor
? Enter application_display_name: My Editor
? Enter version: 0.1.0
Create a new Warp Kernel UI extension using the
repo template new
command:Linux:
./repo.sh template new
Windows:
.\repo.bat template new
Follow the prompt instructions, choosing:
? Select with arrow keys what you want to create: Extension
? Select with arrow keys your desired template: Warp Kernel UI
? Enter name of extension [name-spaced, lowercase, alphanumeric]: my_company.warp_kernel_ui
? Enter extension_display_name: Warp Kernel UI
? Enter version: 0.1.0
Add the Warp Kernel UI extension to the
.kit
file for the Base Editor application. Within thesource/apps/my_company.my_editor.kit
file, add the following line to thedependencies
section:"my_company.warp_kernel_ui" = {}
Build and launch the Base Editor application:
Linux:
./repo.sh build
Windows:
.\repo.bat build
Linux:
./repo.sh launch
Windows:
.\repo.bat launch
The launch tool will prompt you to select an application
.kit
file to launch. Selectmy_company.my_editor.kit
Within the Base Editor application, you should see a new button labeled “Run Kernel”. Clicking this button will launch the Warp kernel and print the results to the console.
4. Cleanup
Before continuing to the next section, it is recommended to clean up the applications, extensions, and any other repository changes that were created during this exploration.
Either revert all changes made to the repository or delete the repository and clone it again before continuing.
Typical cleanup steps include:
Revert changes to top level
premake5.lua
fileRevert changes to
repo.toml
Delete the
source/
directoryDelete the
_build/
directory, or run./repo.sh build -c
or.\repo.bat build -c