The Omniverse Kit SDK

Omniverse Kit App Architecture

At its core, the Omniverse Kit SDK is a framework for efficiently managing extensions and plugins. It provides the tooling necessary for developers to assemble a blend of NVIDIA-provided and custom-developed extensions to create rich, full-featured applications.

Graphical Kit App Stack

The image above illustrates one example of how components can be assembled, showcasing the interplay between the Kit Kernel and extensions to create interactive applications.


Components of Kit SDK

Kit Kernel Package

Central to the SDK, the Kit Kernel Package manages the execution lifecycle of extensions within a given application and facilitates client-server interactions with the Kit framework.

Key Features

  • Extension System: Manages the extension lifecycle process.

  • Event System: Manages communication between application components.

  • Update Loop: Ensures all required components are updated appropriately throughout the application lifecycle.

Kit SDK Extensions

The Kit SDK comes with a set of foundational extensions for rendering, asset management, UI development, and more, acting as the foundational toolkit for application creation.

  • Highlighted Extensions

    • omni.usd: Provides synchronous/asynchronous interfaces to manage UsdContext and query state.

    • omni.kit.commands: Used to register and execute Commands

    • omni.kit.viewport.window: Manages the HydraEngine viewport and its interactions.

    • omni.ui: The Omniverse UI framework


Building with Kit SDK

The Omniverse Kit SDK is a framework designed to accelerate the development of applications based on OpenUSD for a wide variety of use cases. At the heart of this development process are the concepts of extensions and applications.

Extensions

The Kit platform is highly modular; everything is an extension. Extensions are uniquely named and versioned packages, loaded at runtime, and can include Python code, shared libraries, along with C++ or Python APIs, and more. Extensions can be developed independently and can depend on other extensions, offering a high degree of flexibility. They serve as the fundamental building blocks for creating a wide range of applications, from fully-fledged graphical editors to headless services for processing OpenUSD scenes. Developers can develop their own extensions or leverage extensions provided by NVIDIA via the Kit SDK or an NVIDIA managed extension registry.

Structure and Usage: Each extension consists of a dedicated folder containing its source code, assets/data, and a configuration (extension.toml) file.

[extensions-folder]
└── sample.extension
    ├── config
    │   └── extension.toml
    ├── data
    │   ├── icon.png
    │   └── preview.png
    ├── docs
    │   ├── CHANGELOG.md
    │   └── README.md
    ├── sample
    |   └── extension
    |       ├── __init__.py
    |       └── extension.py
    └── premake5.lua

The structure example above illustrates the typical setup for a Python-based extension with dependencies and configuration details declared within the extension.toml file and any custom functionality defined within extension.py. The premake5.lua file defines information for the build system as to where to find specific extension assets. Additional information on configuration details will be shared in a later section.

Applications

Applications essentially assemble selected extensions defined within a .kit file. The .kit file can be viewed as a single-file extension and acts as a manifest, outlining the necessary extensions and their configuration to provide a specific set of application-level functionality.

Building an application is straightforward - specify the extensions it includes, and set default configurations.

[package]
title = "Sample Service"
version = "0.1.0"
description = "This Simple application shows you how to make a Kit Service."
keywords = ["app"]

[dependencies]
"my_company.my_service.setup" = {}

[settings]
folders.'++' = ["${app}/../exts", "${app}/../extscache/"]

The sample .kit file above shows a configuration for a simple service. It defines the application package details, its dependencies, along with any required settings (e.g. local extension search paths). Additional information on configuration details will be shared in a later section.

Dependency Management:

An application is the endpoint of a dependency chain and, therefore, requires careful selection of extension versions. Kit facilitates this by resolving and enabling the latest compatible versions of each extension, allowing for dynamic updates while maintaining a stable environment. We will examine how tooling can help with this in the hands-on section below.

More Information:

For more information on building with The Omniverse Kit SDK, refer to the Omniverse Kit SDK Manual


Hands-on Exploration

This segment walks you through a practical exploration of the Kit SDK, highlighting its core function and capabilities. This hands-on approach will underscore the inherently modular nature of Kit SDK, emphasizing its design as an extension-driven framework.

1. Setup

Our first step is to create a basic application using the kit-app-template tooling. This is primarily done to ensure that an instance of the kit SDK is available in a common location for further exploration. From within the kit-app-template directory, perform the following setup:

Create an Application:

Linux:

./repo.sh template new

Windows:

.\repo.bat template new

Follow the prompt instructions:

  • ? 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]: accept default

  • ? Enter application_display_name: accept default

  • ? Enter version:: accept default

Build your application:

Linux:

./repo.sh build

Windows:

.\repo.bat build

2. Just Kit

To understand what Kit is at its core, let’s attempt to run Kit without any arguments. This operation reveals Kit’s primary role – an SDK framework for managing extensions and plugins.

Linux

./_build/linux-x86_64/release/kit/kit

Windows

.\_build\windows-x86_64\release\kit\kit.exe

When we run the above commands, we are greeted with the following help message:

kit Usage:
 kit [APP_CONFIG] [--exec SCRIPT ARGS...] [--</path/to/key>=<value>] [--enable EXT_ID] [--ext-folder PATH]

[APP_CONFIG]: Pass to app configuration file.
--help, -h: this help message
--info, -v: show info log output in console
--verbose, -vv: show verbose log output in console
--merge-config, -m=<file>: merge configuration file.
--enable EXT_ID: Enable extension (short hand to add extension to enabled list).
--ext-folder PATH: Add extension folder to look extensions in.
--ext-path PATH: Add direct extension path (allows adding single extension).
--publish EXT_ID: Publish extension to the registry and quit.
--publish-overwrite: Allow overwriting extension in registry when publishing.
--unpublish EXT_ID: Unpublish extension from the registry and quit.
--update-exts: Look for latest versions in extension registry and update for all enabled extensions.
--list-exts: List all local extensions and quit.
--list-registry-exts: List all registry extensions and quit.
--disable-ext-startup: Do not startup any extensions, only load them.
--ext-precache-mode: Only resolve and download all extensions, exit right after.
--portable: Enable portable mode. Portable root defaults to ${kit} path.
--portable-root PATH: Enable portable mode and place data/cache/logs folders there.
--reset-user: Do not load persistent settings from user.config file.
--clear-data: Clear $data folder before starting.
--clear-cache: Clear $cache folder before starting.
--exec SCRIPT ARGS..., -e SCRIPT ARGS...: execute a console command on startup
--</path/to/key>=<value>: instruct to supersede configuration key with given value.
--allow-root: do not exit when kit is run as root (or set envvar: OMNI_KIT_ALLOW_ROOT=1).
--wait-debugger, -d: Suspend execution and wait for debugger to attach.

Usage hints:
	use --/ syntax to override any setting. For instance use: --/app/printConfig=true to print startup configuration.

Kit Version: 106.0+release.150019.4245f321.tc
Press any key to continue...

At first, this may seem counter-intuitive. However, Kit at its core is merely a framework for loading and managing extensions/plugins provided by the user. Without any arguments, we’ve effectively launched the framework itself, but haven’t actually enabled any extensions yet.

At this stage, it’s crucial to grasp the concept that Kit is fundamentally about orchestrating extensions.

3. Enabling Extensions

Next, we investigate the extensions packaged with Kit and how to enable an extension.

Kit SDK Extensions

To list extensions included with Kit, execute:

Linux

./_build/linux-x86_64/release/kit/kit --list-exts

Windows

.\_build\windows-x86_64\release\kit\kit.exe --list-exts

The resulting list will include extensions bundled with the Kit SDK. These extensions can be enabled without any additional installation steps. If extensions are enabled that do not appear on this list, Kit will look to local extension search paths and/or the public extension registry for the most recent (or specified) version.

Let’s launch Kit with an extension

Linux

./_build/linux-x86_64/release/kit/kit --enable omni.usd

Windows

.\_build\windows-x86_64\release\kit\kit.exe --enable omni.usd

This will result in a set of extensions being started up and subsequently shutdown. The ordering of this startup and shutdown is consistent with the dependencies specified in each extension. That is, if Extension A depends on Extension B, then B will be started up before A and A will be shutdown before B.

As a follow up, consider

Linux

./_build/linux-x86_64/release/kit/kit --enable omni.kit.mainwindow

Windows

.\_build\windows-x86_64\release\kit\kit.exe --enable omni.kit.mainwindow

This will launch an empty graphical Kit application window. In addition, it will initialize the Kit runtime loop which will keep the window open until the user exits the application.

To Exit: Ctrl+C

In some cases, it may be useful to exit the runtime loop after a specified number of frames. This can be done using the --/app/quitAfter option. For example, to exit after 100 frames:

Linux

./_build/linux-x86_64/release/kit/kit --enable omni.kit.mainwindow --/app/quitAfter=100

Windows

.\_build\windows-x86_64\release\kit\kit.exe --enable omni.kit.mainwindow --/app/quitAfter=100
  • Conclusion and Guidelines

These examples demonstrate the importance of having a modular, sparse, and semantically consistent set of dependencies in our extensions. For example, if we are developing a headless Kit based service, we want to make sure that omni.kit.mainwindow is not (directly or indirectly) listed as a dependency as it would unnecessarily launch a graphical application window for a headless application. In contrast, if the application requires the ability to query and manipulate USD scenes, we would most likely want to include omni.usd as a dependency or rely on a higher-level extension that includes it.

When considering whether to include a dependency, ask yourself the following question

Do I need the application-level functionality provided by this dependency?

4. Launching an Application

As mentioned previously applications are defined through a .kit file, which can be viewed as a single-file extension and acts as a manifest for the necessary extensions and their configuration. Let’s launch the application we created earlier.

Linux

./_build/linux-x86_64/release/kit/kit  _build/linux-x86_64/release/apps/my_company.my_editor.kit

Windows

.\_build\windows-x86_64\release\kit\kit.exe _build\windows-x86_64\release\apps\my_company.my_editor.kit

This will bring up the base editor application we created during setup.

Note: If this is the first time you are launching a graphical application, it may take 5-8 minutes as shaders compile for the first time

With all of this in mind we can now take a look at how some of the tooling provided by the kit-app-template works to provide convenience and consistency in the development process. For example, the repo launch tool is essentially a convenient wrapper around the command we have seen above. It is also able to enable a predefined set of extensions currently defined as the dev-bundle. Adding this flag to the launch command merely uses the --enable flag to add the extension omni.kit.developer.bundle to the command line call for the Kit SDK. The following are equivalent

Linux

./repo.sh launch --dev-bundle

Windows

.\repo.bat launch --dev-bundle

Is equivalent to:

Linux

./_build/linux-x86_64/release/kit/kit  _build/linux-x86_64/release/apps/my_company.my_editor.kit --enable omni.kit.developer.bundle

Windows

.\_build\windows-x86_64\release\kit\kit.exe _build\windows-x86_64\release/apps/my_company.my_editor.kit --enable omni.kit.developer.bundle

5. 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 file

  • Revert changes to repo.toml

  • Delete the source/ directory

  • Delete the _build/ directory, or run ./repo.sh build -c or .\repo.bat build -c


Additional Resources

  • Omniverse Carbonite SDK: Provides cross platform stable interfaces with system components for input, audio, and more. Carbonite is a key component of the Kit Kernel.

  • Omniverse Client Library : Handles communication between Omniverse clients and Omniverse servers. Omniverse Client Library is a key component of the Kit Kernel.

  • Omniverse Kit Core IApp Interface : A plugin that defines the minimal set of functionality that Kit Core provides, extension management, a general message bus, and more. The Core IApp Interface is a key component of the Kit Kernel.