Develop a Simple App
This section provides an introduction to Application development and presents important foundational knowledge:
How Applications and Extensions are defined in
.kit
and.toml
files.How to explore existing Extensions and adding them to your Application.
How user settings can override Application configurations.
Controlling Application window layout.
Kit and Toml Files
If you have developed solutions before you are likely to have used configuration files. Configuration files present developers with a “low-code” approach to changing behaviors. With Kit SDK you will use configuration files to declare:
Package metadata
Dependencies
Settings
Kit allows Applications and Services to be configured via .kit
files and Extensions via .toml
files. Both files present the same ease of readability and purpose of defining a configuration -
they simply have different file Extensions.
Let’s create a .kit
file and register it with the build system:
Create a Kit file:
Create a file named
my_company.my_app.kit
in.\source\apps
.Add this content to the file:
[package] title = "My App" description = "An Application created from a tutorial." version = "2023.0.0" [dependencies] "omni.kit.uiapp" = {} [settings] app.window.title = "My App" [[test]] args = [ "--/app/window/title=My Test App", ]
Configure the build tool to recognize the new Application:
Open
.\premake5.lua
.Find the section
-- Apps:
.Add an entry for the new app:
define_app("my_company.my_app")
.
Run the build command.
Start the app:
Windows:
.\_build\windows-x86_64\release\my_company.my_app.bat
Linux:
./_build/linux-x86_64/release/my_company.my_app.sh
Congratulations, you have created an Application!
Let’s review the sections of .kit
and .toml
files:
Package
[package]
title = "My App"
description = "An Application created from a tutorial."
version = "2023.0.0"
This section provides information used for publishing and displaying information about the
Application/Extension. For example, version = "2023.0.0"
is used both in publishing and UI: a publishing process
can alert a developer that the given version has already been published and the version can
be shown in an “About Window” and the Extension Manager.
Dependencies
[dependencies]
"omni.kit.uiapp" = {}
Dependencies section is a list of Extensions used by the Application/Extension.
The above reference "omni.kit.uiapp" = {}
points to the most recent
version available but can be configured to use specific versions.
Example of an Extension referenced by a specific version:
"omni.kit.converter.cad" = {version = "200.1", exact = true}
The dependencies can be hosted in Extension Registries for on-demand download or in various locations on the local workstation - including inside a project like kit-app-template.
Settings
[settings]
app.window.title = "My App"
Settings provide a low-code mechanism to customize Application/Extension behavior. Some settings modify UI and others modify functionality - it all depends on how an Application/Extension makes use of the setting. An Omniverse developer should consider exposing settings to developers - and end users - to make Extensions as modular as possible.
Experiment
Change the title to My Company App
- app.window.title = "My Company App"
- and run the app again -
still, no build required.
Note the Application title bar shows the new name.
Test
The test section can be thought of as a combined dependencies and settings section. It allows adding dependencies and settings for when running an Application and Extension in test mode.
[[test]]
args = [
"--/app/window/title=My Test App",
]
We will cover this in greater detail later.
Explore NVIDIA Extensions
The Extension Manager window is a tool for developers to explore Extensions created on the Omniverse platform. It lists Extensions created by NVIDIA, the Omniverse community, and can be configured to list Extensions that exist on a local workstation. Let’s add the Extension Manager to the app so we can look for dependencies to add.
Add Extension Manager.
Open
.\source\apps\my_company.my_app.kit
.Add dependency
omni.kit.window.extensions
. Dependencies section should read:
[dependencies] "omni.kit.uiapp" = {} "omni.kit.window.extensions" = {}
In order to point the Extension Manager to the right Extension Registry we need to add the following settings:
# Extension Registries [settings.exts."omni.kit.registry.nucleus"] registries = [ { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/shared" }, { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" }, ]
Observe that - once you save the source kit file - the corresponding kit file in the build directory was updated as well. This is due to the use of symlinks. A build is not necessary when editing .kit files. See:
Windows:
.\_build\windows-x86_64\release\apps\my_company.my_app.kit
Linux:
./_build/linux-x86_64/release/apps/my_company.my_app.kit
Explore Extensions in Extension Manager.
Start the app:
Windows:
.\_build\windows-x86_64\release\my_company.my_app.bat
Linux:
./_build/linux-x86_64/release/my_company.my_app.sh
Open Extension Manager:
Window
>Extensions
.Please allow Extension Manager to sync with the Extension Registry. The listing might not load instantly.
Search for
graph editor example
. The Extension Manager should listomni.kit.graph.editor.example
in the NVIDIA tab.
Click
INSTALL
.Click the toggle
DISABLED
to enable Extension.
Check
AUTOLOAD
.
Close the app and start again.
Observe that the Graph Editor Example Extension is enabled. Look at the
[dependencies]
section in.\source\apps\my_company.my_app.kit.
Theomni.kit.graph.editor.example
Extension is not listed. The point here is to make it clear that when an Extension is enabled by a user in the Extension Manager, the dependency is NOT added to the Application.kit
file. The reason the Extension is still enabled in the app is due to user settings. Let’s explore that topic in more detail…
User Settings
Kit Applications allow a user’s choices and settings to persist between sessions. Configurations
like these are stored in a user.config.json
file. The default location for this file is
the Omniverse Launcher
DATA PATH
: [data path]\Kit\[application name]\[application version]\user.config.json
.
If you are not using Omniverse Launcher - or you cannot find the location of the
user.config.json
file for whatever reason - look at the first lines of the Application log.
Look for the line that starts with Loading user config located at:
.
Inspecting the file for this tutorial you should see this section:
"exts": {
"enabled": {
"0": "omni.kit.graph.editor.example-1.0.22"
}
}
When you uncheck AUTOLOAD
for omni.kit.graph.editor.example
in the Extension Manager you’ll notice the
user.config.json
file is no longer listing the Extension as enabled.
Note
Because the config file can store both custom enabled Extensions and custom settings, as a developer you may
want to at times delete your user.config.json
file for the app you are developing to make sure you are
viewing the Application like an end user will when they use it in its default state.
Note
As a developer, we recommend that you refrain from using the AUTOLOAD
functionality unless you truly want to
enable an Extension without making it permanently available in the Application.
Dependency Hierarchy
While the selected Extension is ENABLED
, select the DEPENDENCIES
tab and click the Toggle View
button.
It might take a few seconds for the UI to refresh.
The Extension Manager presents up and downstream dependencies. This is useful for discovering how one Extension is composed of many. It’s also a convenient way to find where an Extension is being referenced from.
Explore Community Extensions
Extensions developed by the community are not really any different from NVIDIA Extensions, they are just stored in a different location and have not been vetted by NVIDIA the same way NVIDIA Extensions have. That’s not to say they have not been through rigorous tests - they have simply not been through the NVIDIA release pipeline.
There are two settings that need to be added to the Application to make use of community Extensions.
Add
app.extensions.installUntrustedExtensions = true
to enable the app to install and load community Extensions.
[settings]
app.window.title = "My Company App"
app.extensions.installUntrustedExtensions = true
Add the URL to the Community Extension Registry by modifying the
registries
setting.
# Extension Registries
[settings.exts."omni.kit.registry.nucleus"]
registries = [
{ name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/shared" },
{ name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
{ name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
]
Restart the app and allow Extension Manager to sync with the Extension Registry. The listing might not load instantly. You can now experiment by adding community Extensions such as
"heavyai.ui.component" = {}
to the[dependencies]
section.
Add Extensions
Let’s assume we found a few Extensions we want to use. Add the below
[dependencies]
section to themy_company.my_app.kit
Application. The Extension Manager has been removed since that is a developer tool.
[dependencies]
"omni.kit.uiapp" = {}
# Viewport
"omni.kit.viewport.bundle" = {}
# Render Settings
"omni.rtx.window.settings" = {}
# Content Browser
"omni.kit.window.content_browser" = {}
# Stage Inspector
"omni.kit.window.stage" = {}
# Layer Inspector
"omni.kit.widget.layers" = {}
# Toolbar. Setting load order so that it loads last.
"omni.kit.window.toolbar" = { order = 1000 }
# Properties Inspector
"omni.kit.property.bundle" = {}
# DX shader caches (windows only)
[dependencies."filter:platform"."windows-x86_64"]
"omni.rtx.shadercache.d3d12" = {}
Add this setting:
app.content.emptyStageOnStart = true
Run the app again. It’ll look something like this:
Application Layout
The Application window layout is fairly organized already but let’s take care of the floating Content Browser by docking it below the viewport window.
Add a Resource Extension
Extensions do not need to provide code. We use so-called “resource Extensions” to provide assets, data, and anything else that can be considered a resource. In this example we create it to provide a layout file.
Create a new Extension using
repo template new
command (command cheat-sheet).For
What do you want to add
chooseextension
.For
Choose a template
choosepython-extension-simple
.Enter an all new name:
my_company.my_app.resources
. Do not use the default name.Leave version as
0.1.0
.The new Extension is created in
.\source\extensions\my_company.my_app.resources
.
Add a
layouts
directory insidemy_company.my_app.resources
. We’ll be adding a resource file here momentarily.Configure the build to pick up the
layouts
directory by adding a{ "layouts", ext.target_dir.."/layouts" },
in the Extension’s.\my_company.my_app.resources\premake5.lua
file:
-- Use folder name to build Extension name and tag. Version is specified explicitly.
local ext = get_current_extension_info()
-- That will also link whole current "target" folder into as extension target folder:
project_ext (ext)
repo_build.prebuild_link {
{ "data", ext.target_dir.."/data" },
{ "docs", ext.target_dir.."/docs" },
{ "layouts", ext.target_dir.."/layouts" },
{ "my_company", ext.target_dir.."/my_company" },
}
Configure App to Recognize Extensions
By default, Extensions that are part of the Kit SDK will be recognized by Applications. When we add Extensions like the
one above we need to add paths to the Application’s .kit file. The below adds the paths for these additional Extensions.
Note the use of ${app}
as a token. This will be replaced with the path to the app at runtime.
Add this to the my_company_my_app.kit
:
[settings.app.exts]
# Add additional search paths for dependencies.
folders.'++' = ["${app}/../exts", "${app}/../extscache/"]
Note
Reference: Tokens
Configure App to Provide Layout Capabilities
Add these Extensions to the my_company_my_app.kit
[dependencies]
section. omni.app.setup
provides layout capabilities.
# Layout capabilities
"omni.app.setup" = {}
# App resources
"my_company.my_app.resources" = {}
Create a Layout File
Run a build to propagate the new Extension to the built solution and start the app.
Drag and drop the
Content Browser
on top of the lower docker manipulator within theViewport
window.
Save the layout:
Use menu
Window
>Layout
>Save Layout...
command.Save the layout as
.\source\extensions\my_company.my_app.resources\layouts\layout.json
.
Use Layout
Add this to the
my_company.my_app.kit
files[settings]
section. Again, here we are using a token:${my_company.my_app.resources}
. That token is replaced with the path to the Extension at runtime:
app.kit.editor.setup = true
app.layout.default = "${my_company.my_app.resources}/layouts/layout.json"
Run a build so the
layouts
directory with itslayout.json
file is created in the_build
directory structure.Run the Application again and see the
Content Browser
being docked.
A developer can provide end users with different layouts - or workflows
. This topic can be further explored in the
omni.app.setup reference.
You now have an Application and could skip ahead to the Package App and Publish App sections; however, this tutorial now continues with a more advanced example: Develop a USD Explorer App.