├── tools ├── deps │ ├── user.toml │ ├── kit-sdk.packman.xml │ ├── repo-deps.packman.xml │ ├── kit-sdk-deps.packman.xml │ └── pip.toml ├── VERSION.md ├── containers │ ├── stream_sdk.txt │ ├── kit_args.txt │ ├── entrypoint_memcached.sh.j2 │ ├── entrypoint.sh.j2 │ └── Dockerfile.j2 ├── isaacsim │ └── data │ │ ├── python │ │ ├── shared │ │ │ ├── requirements.txt │ │ │ ├── tensorboard │ │ │ └── environment.yml │ │ ├── linux-x86_64 │ │ │ ├── icon │ │ │ │ ├── omni.isaac.sim.png │ │ │ │ └── install_icon.py │ │ │ ├── setup_conda_env.sh │ │ │ ├── python.sh │ │ │ └── jupyter_notebook.sh │ │ └── windows-x86_64 │ │ │ └── python.bat │ │ ├── jupyter_kernel │ │ └── kernel.json │ │ └── python_packages │ │ └── isaacsim │ │ └── __init__.py ├── package.bat ├── package.sh ├── packman │ ├── config.packman.xml │ ├── python.bat │ ├── python.sh │ ├── bootstrap │ │ ├── fetch_file_from_packman_bootstrap.cmd │ │ ├── download_file_from_url.ps1 │ │ ├── install_package.py │ │ └── configure.bat │ ├── packman.cmd │ └── packmanconf.py └── repoman │ ├── repoman.py │ └── repoman_bootstrapper.py ├── templates ├── extensions │ ├── basic_cpp │ │ ├── template │ │ │ ├── docs │ │ │ │ ├── Overview.md │ │ │ │ ├── README.md │ │ │ │ └── CHANGELOG.md │ │ │ ├── data │ │ │ │ ├── icon.png │ │ │ │ └── preview.png │ │ │ ├── tests.cpp │ │ │ │ └── CppExampleTest.cpp │ │ │ ├── premake5.lua │ │ │ ├── config │ │ │ │ └── extension.toml │ │ │ └── plugins │ │ │ │ └── {{extension_name}} │ │ │ │ └── CppExtension.cpp │ │ └── README.md │ ├── python_ui │ │ ├── template │ │ │ ├── docs │ │ │ │ ├── Overview.md │ │ │ │ ├── README.md │ │ │ │ └── CHANGELOG.md │ │ │ ├── data │ │ │ │ ├── icon.png │ │ │ │ └── preview.png │ │ │ ├── premake5.lua │ │ │ ├── {{python_module_path}} │ │ │ │ ├── __init__.py │ │ │ │ ├── tests │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── test_hello_world.py │ │ │ │ └── extension.py │ │ │ └── config │ │ │ │ └── extension.toml │ │ └── README.md │ ├── basic_python │ │ ├── template │ │ │ ├── docs │ │ │ │ ├── Overview.md │ │ │ │ ├── README.md │ │ │ │ └── CHANGELOG.md │ │ │ ├── data │ │ │ │ ├── icon.png │ │ │ │ └── preview.png │ │ │ ├── premake5.lua │ │ │ ├── {{python_module_path}} │ │ │ │ ├── __init__.py │ │ │ │ ├── tests │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test_hello.py │ │ │ │ │ └── test_benchmarks.py │ │ │ │ └── extension.py │ │ │ └── config │ │ │ │ └── extension.toml │ │ └── README.md │ └── basic_python_binding │ │ ├── template │ │ ├── data │ │ │ ├── icon.png │ │ │ └── preview.png │ │ ├── docs │ │ │ ├── CHANGELOG.md │ │ │ └── Overview.md │ │ ├── python │ │ │ ├── tests │ │ │ │ ├── __init__.py │ │ │ │ └── test_pybind_example.py │ │ │ └── impl │ │ │ │ ├── __init__.py │ │ │ │ └── example_pybind_extension.py │ │ ├── bindings │ │ │ └── python │ │ │ │ └── {{extension_name}} │ │ │ │ ├── __init__.py │ │ │ │ └── ExamplePybindBindings.cpp │ │ ├── include │ │ │ ├── omni │ │ │ │ └── example │ │ │ │ │ └── cpp │ │ │ │ │ └── pybind │ │ │ │ │ ├── {{object_interface_name}}.h │ │ │ │ │ ├── {{object_name}}.h │ │ │ │ │ └── {{interface_name}}.h │ │ │ └── {{python_module_path}} │ │ │ │ ├── {{object_interface_name}}.h │ │ │ │ ├── {{object_name}}.h │ │ │ │ └── {{interface_name}}.h │ │ ├── premake5.lua │ │ ├── config │ │ │ └── extension.toml │ │ └── plugins │ │ │ ├── {{extension_name}} │ │ │ └── ExamplePybindExtension.cpp │ │ │ └── {{extension_name}}.tests │ │ │ └── ExamplePybindTests.cpp │ │ └── README.md ├── apps │ └── isaacsim_configs │ │ ├── README.md │ │ ├── isaacsim.exp.template.ros2.kit │ │ ├── isaacsim.exp.template.zero_delay.kit │ │ ├── isaacsim.exp.template.fabric.kit │ │ ├── isaacsim.exp.template.streaming.kit │ │ └── isaacsim.exp.template.replicator.kit └── templates.toml ├── readme-assets ├── cpp_logo.png ├── kit_service.png ├── usd_composer.jpg ├── usd_viewer.jpg ├── vs_additional.png ├── vs_download.png ├── vs_modify.png ├── vs_workloads.png ├── isaacsim_full.png ├── kit_base_editor.png ├── python-logo-only.png ├── streaming_viewer.png ├── usd_explorer.jpg ├── vs_winsdk_verify.png ├── cpp_python_bindings.png ├── kit_app_template_banner.png ├── streaming_base_editor.png ├── streaming_composer.png ├── streaming_explorer.png ├── python_ui_extension_template.jpg ├── usd_explorer_default_launch.png ├── usd_viewer_default_launch.png ├── usd_composer_default_launch.png ├── usd_viewer_load_asset_desktop.png └── additional-docs │ ├── data_collection_and_use.md │ ├── developer_bundle_extensions.md │ ├── kit_app_streaming_config.md │ └── windows_developer_configuration.md ├── .editorconfig ├── repo_tools.toml ├── source ├── standalone_examples │ └── hello_world.py └── apps │ └── isaacsim.exp.base.zero_delay.kit ├── .gitignore ├── .vscode ├── launch.json ├── tasks.json └── template_builder.py ├── .gitattributes ├── .github └── ISSUE_TEMPLATE │ ├── question.yml │ ├── feature_request.yml │ └── bug_report.yml ├── premake5.lua ├── repo.bat ├── repo.sh └── SECURITY.md /tools/deps/user.toml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/VERSION.md: -------------------------------------------------------------------------------- 1 | 5.1.0 2 | -------------------------------------------------------------------------------- /tools/containers/stream_sdk.txt: -------------------------------------------------------------------------------- 1 | SenderTimeout=1000000 -------------------------------------------------------------------------------- /tools/isaacsim/data/python/shared/requirements.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/docs/Overview.md: -------------------------------------------------------------------------------- 1 | # Overview -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/docs/Overview.md: -------------------------------------------------------------------------------- 1 | # Overview -------------------------------------------------------------------------------- /tools/package.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | call "%~dp0..\repo" package %* 3 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/docs/Overview.md: -------------------------------------------------------------------------------- 1 | # Overview -------------------------------------------------------------------------------- /tools/package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | SCRIPT_DIR=$(dirname ${BASH_SOURCE}) 4 | source "$SCRIPT_DIR/../repo.sh" package $@ || exit $? 5 | -------------------------------------------------------------------------------- /readme-assets/cpp_logo.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a5f3cb45e0b279f929e4c314e176d6cb04428a4d88504e7eec8df1a5f8b35de5 3 | size 46138 4 | -------------------------------------------------------------------------------- /readme-assets/kit_service.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e64b244101cee1cfb3b43caa8f5617bfbb4cd5ee01e69cf713ee73916d90e2bf 3 | size 69387 4 | -------------------------------------------------------------------------------- /readme-assets/usd_composer.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:412c0a48fd4568b26ef168907adf1fc2ad4c21ae9720108b071323424149f468 3 | size 170164 4 | -------------------------------------------------------------------------------- /readme-assets/usd_viewer.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:402968fe8fd8369e374a00e06a3affac4a9d127c1cb7e02b197b8a7d5ba624f9 3 | size 64781 4 | -------------------------------------------------------------------------------- /readme-assets/vs_additional.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:efc5984dbeaa68c2474a10934f1795f81b71331b94a770f794a8713a69f5ee56 3 | size 45920 4 | -------------------------------------------------------------------------------- /readme-assets/vs_download.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:72d8194ba099532db706fb95b9ad0c992f0be8b588dea0c7f832a72041f155c0 3 | size 217607 4 | -------------------------------------------------------------------------------- /readme-assets/vs_modify.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:822040e437b2ab7c0da8d5341555def09c8cc0d93482a4a1f68ed109a27b28b0 3 | size 17533 4 | -------------------------------------------------------------------------------- /readme-assets/vs_workloads.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:685697bbcc3cb75ca56f3fc685be9608b4d2405b81dc9bd2fc072096cb934883 3 | size 35114 4 | -------------------------------------------------------------------------------- /readme-assets/isaacsim_full.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ca1b10d5d895440a640514ed825191471b2f9f41bd57f8d15477c61bf14d08a7 3 | size 246618 4 | -------------------------------------------------------------------------------- /readme-assets/kit_base_editor.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fa2a2ea71408238462ba9159b6cc3c9528a06cd4f6758e40fc7058c717e67bb1 3 | size 201911 4 | -------------------------------------------------------------------------------- /readme-assets/python-logo-only.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4008a934b415c152bfa513be3e9b05de4212ae41549a27f2c6c8d41b3a24a4da 3 | size 20637 4 | -------------------------------------------------------------------------------- /readme-assets/streaming_viewer.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a1185e9e0b211c78b25662db41d3b11ef61e8908f056c02b868385d698875109 3 | size 1566282 4 | -------------------------------------------------------------------------------- /readme-assets/usd_explorer.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e0826ae01a53765ec3d75a2d87589af38e9082d17999e02b2fd5665504e283ce 3 | size 1177164 4 | -------------------------------------------------------------------------------- /readme-assets/vs_winsdk_verify.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eb99ae3ddafd665efefc4499168243a287d2f4f111d05d5dfcaf00bfde23ae8f 3 | size 23712 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/docs/README.md: -------------------------------------------------------------------------------- 1 | # {{ extension_display_name }} [{{ extension_name }}] 2 | 3 | Simple example of an extension that loads a C++ plugin. 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | indent_size = 4 4 | charset = utf-8 5 | trim_trailing_whitespace = true 6 | max_line_length = 120 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /readme-assets/cpp_python_bindings.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fd404a9ad276f792f83f7fb8a64bc2ede4388bfd3a6c2e0b7d3d9738b3850a65 3 | size 778518 4 | -------------------------------------------------------------------------------- /readme-assets/kit_app_template_banner.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3f9509162be67ff62f817a1fb8c71a947208753f72e8d8ecacaf9b20d09f44cb 3 | size 82611 4 | -------------------------------------------------------------------------------- /readme-assets/streaming_base_editor.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ec02cf8acdf8092de462c0030d1833bea65a3958fd316038b8729c2131c5fb0c 3 | size 421094 4 | -------------------------------------------------------------------------------- /readme-assets/streaming_composer.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:254b042e793fe30f1cc50011ecb0939abc440922e907c8367030fa7bf85f5a60 3 | size 1066438 4 | -------------------------------------------------------------------------------- /readme-assets/streaming_explorer.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c8c643c7255b5093fa5b09d17d300b3db3ec0d49f8a00006afc012dc0ff7ffe3 3 | size 456984 4 | -------------------------------------------------------------------------------- /readme-assets/python_ui_extension_template.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2b0bab582463e7fe314acc862de6262ec711fbbe70dff89a308934e481c8d281 3 | size 9478 4 | -------------------------------------------------------------------------------- /readme-assets/usd_explorer_default_launch.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6dc93203cac9ee889baba6388645ef7a6880fe34e8f175622dd1f8c8caf5ff32 3 | size 295907 4 | -------------------------------------------------------------------------------- /readme-assets/usd_viewer_default_launch.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:97f7d06567192daab9c293d67a58fe83de1556eaebec123af3105c9808353b53 3 | size 16543 4 | -------------------------------------------------------------------------------- /readme-assets/usd_composer_default_launch.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1963f87a56e117244dfc1f75ec860647a897467186b32fa7a6712c273475407e 3 | size 1295338 4 | -------------------------------------------------------------------------------- /readme-assets/usd_viewer_load_asset_desktop.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f623a33785dfafd43b220d1e1d502a609b1ec0b5f993f6e5f20c24409327d913 3 | size 2199740 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/data/icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8e3882f41b9ac9bed5887720c8feb8bd50fd05dc278856fc4252ff55af6c2e6c 3 | size 15146 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/data/preview.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7a065a9aeeda4b9d17fbdea012cd2abf1e1a228b5f3382f85207059729266bea 3 | size 97802 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/data/icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8e3882f41b9ac9bed5887720c8feb8bd50fd05dc278856fc4252ff55af6c2e6c 3 | size 15146 4 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/data/icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8e3882f41b9ac9bed5887720c8feb8bd50fd05dc278856fc4252ff55af6c2e6c 3 | size 15146 4 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/data/preview.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7a065a9aeeda4b9d17fbdea012cd2abf1e1a228b5f3382f85207059729266bea 3 | size 97802 4 | -------------------------------------------------------------------------------- /tools/containers/kit_args.txt: -------------------------------------------------------------------------------- 1 | # These arguments are fed into all containerized application executions via repo launch 2 | "--no-window" 3 | "--ext-folder /home/ubuntu/.local/share/ov/data/exts/v2" -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/data/preview.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7a065a9aeeda4b9d17fbdea012cd2abf1e1a228b5f3382f85207059729266bea 3 | size 97802 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/data/icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8e3882f41b9ac9bed5887720c8feb8bd50fd05dc278856fc4252ff55af6c2e6c 3 | size 15146 4 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/docs/README.md: -------------------------------------------------------------------------------- 1 | # {{ extension_display_name }} [{{ extension_name }}] 2 | 3 | A simple python UI extension example. Use it as a starting point for your extensions. 4 | -------------------------------------------------------------------------------- /tools/isaacsim/data/python/linux-x86_64/icon/omni.isaac.sim.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:40039148d0c6811eceecec0f8bfd370d27ce8bc404d9e89fbe6d7a22f0cf3276 3 | size 16478 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/data/preview.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:561aed4cf5b9fc7c158c070a66748086a353422048b85ef5df608a958512e1c3 3 | size 32827 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/docs/README.md: -------------------------------------------------------------------------------- 1 | # {{ extension_display_name }} [{{ extension_name }}] 2 | 3 | This is an example of pure python Kit extension. It is intended to be copied and to serve as a template to create new ones. 4 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.0.1] - 2023-04-27 4 | ### Updated 5 | - Build against Kit 105.0 6 | 7 | ## [1.0.0] - 2022-06-30 8 | ### Added 9 | - Initial implementation. 10 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 4 | 5 | 6 | ## [{{ version }}] - {{ current_date }} 7 | - Initial version of basic C++ extension template 8 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 4 | 5 | 6 | ## [{{ version }}] - {{current_date}} 7 | - Initial version of basic python extension template 8 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 4 | 5 | 6 | ## [{{ version }}] - {{current_date}} 7 | - Initial version of extension UI template with a window 8 | -------------------------------------------------------------------------------- /tools/packman/config.packman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/isaacsim/data/jupyter_kernel/kernel.json: -------------------------------------------------------------------------------- 1 | { 2 | "argv": ["AUTOMATICALLY_REPLACED", "-m", "ipykernel_launcher", "-f", "{connection_file}"], 3 | "display_name": "Isaac Sim Python 3", 4 | "language": "python", 5 | "env": { 6 | "ISAAC_JUPYTER_KERNEL": "1" 7 | }, 8 | "metadata": { 9 | "debugger": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tools/deps/kit-sdk.packman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/isaacsim/data/python/shared/tensorboard: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | try: 4 | from tensorboard.main import run_main 5 | except ImportError: 6 | print("Tensorboard is not installed, please run ./python.sh -m pip install -r requirements.txt") 7 | exit() 8 | if __name__ == '__main__': 9 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) 10 | sys.exit(run_main()) -------------------------------------------------------------------------------- /tools/isaacsim/data/python/shared/environment.yml: -------------------------------------------------------------------------------- 1 | name: isaac-sim 2 | channels: 3 | - defaults 4 | - pytorch 5 | - nvidia 6 | dependencies: 7 | - python=3.10 8 | - pip 9 | - pytorch 10 | - torchvision 11 | - torchaudio 12 | - cuda-toolkit=11.7 13 | - pip: 14 | - stable-baselines3==2.0.0 15 | - tensorboard==2.11.0 16 | - tensorboard-plugin-wit==1.8.1 17 | - protobuf==3.20.3 18 | -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/README.md: -------------------------------------------------------------------------------- 1 | # Streaming Configuration Layers 2 | 3 | These `.kit` files, known as `ApplicationLayerTemplates`, are used to define additional functionality added to the base application. 4 | 5 | For streaming configuration layers, these templates define and configure the required streaming extensions. 6 | 7 | :warning: **Important**: These layers are not standalone application templates. They must be used in conjunction with a base application template. -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/premake5.lua: -------------------------------------------------------------------------------- 1 | -- Use folder name to build extension name and tag. Version is specified explicitly. 2 | local ext = get_current_extension_info() 3 | 4 | project_ext (ext) 5 | 6 | -- Link only those files and folders into the extension target directory 7 | repo_build.prebuild_link { 8 | { "data", ext.target_dir.."/data" }, 9 | { "docs", ext.target_dir.."/docs" }, 10 | { "{{ python_module_toplevel }}", ext.target_dir.."/{{ python_module_toplevel }}" }, 11 | } -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/premake5.lua: -------------------------------------------------------------------------------- 1 | -- Use folder name to build extension name and tag. Version is specified explicitly. 2 | local ext = get_current_extension_info() 3 | 4 | project_ext (ext) 5 | 6 | -- Link only those files and folders into the extension target directory 7 | repo_build.prebuild_link { 8 | { "data", ext.target_dir.."/data" }, 9 | { "docs", ext.target_dir.."/docs" }, 10 | { "{{ python_module_toplevel }}", ext.target_dir.."/{{ python_module_toplevel }}" }, 11 | } 12 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/python/tests/__init__.py: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | ## 3 | ## NVIDIA CORPORATION and its licensors retain all intellectual property 4 | ## and proprietary rights in and to this software, related documentation 5 | ## and any modifications thereto. Any use, reproduction, disclosure or 6 | ## distribution of this software and related documentation without an express 7 | ## license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | ## 9 | from .test_pybind_example import * 10 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/python/impl/__init__.py: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | ## 3 | ## NVIDIA CORPORATION and its licensors retain all intellectual property 4 | ## and proprietary rights in and to this software, related documentation 5 | ## and any modifications thereto. Any use, reproduction, disclosure or 6 | ## distribution of this software and related documentation without an express 7 | ## license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | ## 9 | from .example_pybind_extension import * 10 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/{{python_module_path}}/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | from .extension import * 12 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/{{python_module_path}}/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | from .extension import * 12 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/{{python_module_path}}/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | from .test_hello_world import * 12 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/{{python_module_path}}/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | from .test_benchmarks import * 12 | from .test_hello import * 13 | -------------------------------------------------------------------------------- /repo_tools.toml: -------------------------------------------------------------------------------- 1 | ####################################################################################################################### 2 | # [repo_launcher] Simple tool to launch Kit applications 3 | ####################################################################################################################### 4 | 5 | [repo_launch] 6 | command = "launch" 7 | entry_point = "${root}/tools/repoman/launch.py:setup_repo_tool" 8 | 9 | [repo_package] 10 | # Hide default repo_package under internal command to be used by `repo_package_app` 11 | command = "_package" 12 | 13 | [repo_package_app] 14 | # Replace regular repo_package with our guided packaging tool 15 | command = "package" 16 | entry_point = "${root}/tools/repoman/package.py:setup_repo_tool" 17 | enabled = true 18 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/bindings/python/{{extension_name}}/__init__.py: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | ## 3 | ## NVIDIA CORPORATION and its licensors retain all intellectual property 4 | ## and proprietary rights in and to this software, related documentation 5 | ## and any modifications thereto. Any use, reproduction, disclosure or 6 | ## distribution of this software and related documentation without an express 7 | ## license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | ## 9 | 10 | # Necessary so we can link to the Python source instead of copying it. 11 | __all__ = ['"{{object_name}}"', '{{ interface_name }}', '{{ object_interface_name }}', 'acquire_bound_interface', 'release_bound_interface'] 12 | from .impl import * 13 | -------------------------------------------------------------------------------- /source/standalone_examples/hello_world.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. 2 | # 3 | # NVIDIA CORPORATION and its licensors retain all intellectual property 4 | # and proprietary rights in and to this software, related documentation 5 | # and any modifications thereto. Any use, reproduction, disclosure or 6 | # distribution of this software and related documentation without an express 7 | # license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | # 9 | 10 | from isaacsim import SimulationApp 11 | 12 | # The most basic usage for creating a simulation app 13 | kit = SimulationApp() 14 | 15 | import omni 16 | 17 | for i in range(100): 18 | kit.update() 19 | 20 | omni.kit.app.get_app().print_and_log("Hello World!") 21 | 22 | kit.close() # Cleanup application 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # All folders starting with _ are local. 2 | _*/ 3 | 4 | # Compiled python files. 5 | *.py[cod] 6 | 7 | # Visual Studio files. 8 | /.vs 9 | **/.vscode/ipch 10 | 11 | # macOS files. 12 | .DS_Store 13 | 14 | # Generated license file. 15 | PACKAGE-DEPS.yaml 16 | 17 | # packman .user config 18 | *.packman.xml.user 19 | 20 | # kit user config 21 | deps/**/user.toml 22 | 23 | # vscode settings are copied and filled in from 'settings.json.template' 24 | .vscode/settings.json 25 | 26 | # PyCharm files. 27 | /.idea/ 28 | 29 | # Linux in docker build $HOME dirs 30 | /.nvidia-omniverse 31 | /.local 32 | /.cache 33 | 34 | # Omniverse EULA breadcrumb 35 | /.omniverse_eula_accepted.txt 36 | 37 | # Streaming EventTrace 38 | *.etli 39 | 40 | 41 | # Ignore generated templates in source/apps 42 | source/apps/isaacsim.exp.template* -------------------------------------------------------------------------------- /tools/isaacsim/data/python/linux-x86_64/setup_conda_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | if [ -n "$ZSH_VERSION" ]; then 4 | SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" 5 | export BASH_SOURCE=$SCRIPT_DIR/setup_python_env.sh 6 | fi 7 | MY_DIR="$(realpath -s "$SCRIPT_DIR")" 8 | # path=$SCRIPT_DIR 9 | # while [[ $path != / ]]; 10 | # do 11 | 12 | # if ! find "$path" -maxdepth 1 -mindepth 1 -iname "_build" -exec false {} + 13 | # then 14 | # break 15 | # fi 16 | # # Note: if you want to ignore symlinks, use "$(realpath -s "$path"/..)" 17 | # path="$(readlink -f "$path"/..)" 18 | 19 | # done 20 | # build_path=$path/_build 21 | export CARB_APP_PATH=$SCRIPT_DIR/kit 22 | export EXP_PATH=$MY_DIR/apps 23 | export ISAAC_PATH=$MY_DIR 24 | . ${MY_DIR}/setup_python_env.sh 25 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/tests.cpp/CppExampleTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: LicenseRef-NvidiaProprietary 4 | * 5 | * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 6 | * property and proprietary rights in and to this material, related 7 | * documentation and any modifications thereto. Any use, reproduction, 8 | * disclosure or distribution of this material and related documentation 9 | * without an express license agreement from NVIDIA CORPORATION or 10 | * its affiliates is strictly prohibited. 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | CARB_BINDINGS("{{ extension_name }}.tests") 17 | 18 | TEST_SUITE("{{ extension_name }}.tests Test Suite") { 19 | TEST_CASE("Sample Test Case") { 20 | CHECK(5 == 5); 21 | } 22 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Remote Attach", 9 | "type": "debugpy", 10 | "request": "attach", 11 | "connect": { 12 | "host": "localhost", 13 | "port": 3000 14 | }, 15 | "pathMappings": [ 16 | { 17 | "localRoot": "${workspaceFolder}", 18 | "remoteRoot": "${workspaceFolder}" 19 | } 20 | ], 21 | "justMyCode": true, 22 | "subProcess": true, 23 | "runtimeArgs" : [ 24 | "--preserve-symlinks", 25 | "--preserve-symlinks-main" 26 | ] 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /tools/isaacsim/data/python/windows-x86_64/python.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | :: Setup python env from generated file (generated by tools/repoman/build.py) 5 | if exist "%~dp0setup_python_env.bat" ( 6 | call "%~dp0setup_python_env.bat" 7 | ) 8 | 9 | :: The executable path will be where python is located. So we set Cabonite app path through env var: 10 | set CARB_APP_PATH=%~dp0kit 11 | set ISAAC_PATH=%~dp0 12 | set EXP_PATH=%~dp0apps 13 | 14 | :: By default use our python, but allow overriding it by checking if PYTHONEXE env var is defined: 15 | if "%PYTHONEXE%"=="" ( 16 | if not exist "%~dp0kit\python\kit.exe" ( 17 | copy "%~dp0kit\python\python.exe" "%~dp0kit\python\kit.exe" 18 | ) 19 | set PYTHONEXE="%~dp0kit\python\kit.exe" 20 | REM set PYTHONEXE="%~dp0kit\python\python.exe" 21 | ) 22 | 23 | call %PYTHONEXE% %* 24 | 25 | if errorlevel 1 ( goto ErrorRunningPython ) 26 | 27 | :Success 28 | endlocal 29 | exit /B 0 30 | 31 | :ErrorRunningPython 32 | echo There was an error running python. 33 | endlocal 34 | exit /B 1 35 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize text files on commit to LF endings by default 2 | * text=auto 3 | # Make sure Windows batch files preserve CR/LF line endings, otherwise they may not be able to execute. Windows 4 | # batch files require a CR/LF for labels to work properly, otherwise they may fail when labels straddle 512-byte 5 | # block boundaries. This is important when files are downloaded through a zip archive that was authored on a 6 | # Linux machine (the default behavior on GitHub) 7 | *.bat text eol=crlf 8 | *.cmd text eol=crlf 9 | # Make sure shell scripts have LF line endings, even when checked out on a Windows client with autocrlf=true 10 | *.sh text eol=lf 11 | # All files under data go into Git LFS 12 | data/** filter=lfs diff=lfs merge=lfs -text 13 | source/extensions/**/data/** filter=lfs diff=lfs merge=lfs -text 14 | templates/extensions/**/data/** filter=lfs diff=lfs merge=lfs -text 15 | *.png filter=lfs diff=lfs merge=lfs -text 16 | *.exr filter=lfs diff=lfs merge=lfs -text 17 | *.jpg filter=lfs diff=lfs merge=lfs -text 18 | *.usd filter=lfs diff=lfs merge=lfs -text 19 | *.hdr filter=lfs diff=lfs merge=lfs -text 20 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/premake5.lua: -------------------------------------------------------------------------------- 1 | -- Use folder name to build extension name and tag. Version is specified explicitly. 2 | local ext = get_current_extension_info() 3 | 4 | project_ext (ext) 5 | 6 | -- Link only those files and folders into the extension target directory 7 | repo_build.prebuild_link { 8 | { "data", ext.target_dir.."/data" }, 9 | { "docs", ext.target_dir.."/docs" }, 10 | } 11 | 12 | -- Build Carbonite plugin to be loaded by the extension. This plugin implements 13 | -- omni::ext::IExt interface to be automatically started by extension system. 14 | project_ext_plugin(ext, "{{ extension_name }}.plugin") 15 | local plugin_name = "{{ extension_name }}" 16 | add_files("iface", "%{root}/include/omni/ext", "IExt.h") 17 | add_files("impl", "plugins/"..plugin_name) 18 | includedirs { "plugins/"..plugin_name } 19 | 20 | -- To write C++ tests, we have to create a shared library with tests to be loaded 21 | -- project_ext_tests(ext, ext.id..".tests") 22 | -- dependson { ext.id..".plugin" } 23 | -- add_files("impl", "tests.cpp") 24 | -- includedirs { "%{target_deps}/doctest/include" } 25 | -------------------------------------------------------------------------------- /tools/deps/repo-deps.packman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tools/containers/entrypoint_memcached.sh.j2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -u 4 | 5 | USER_ID="$${USER_ID:-""}" 6 | if [ -z "$${USER_ID}" ]; then 7 | echo "User id is not set" 8 | fi 9 | 10 | # INSERT FANCY DRIVER + SHADER CACHE MEMACHED ENVIRONMENT PREP 11 | # PROBABLY NEED TO REFERENCE ENVVAR FOR MEMCACHED SERVER ADDRESS 12 | 13 | CMD="/app/kit/kit" 14 | ARGS=( 15 | "/app/apps/$KIT_FILE_NAME_BREADCRUMB" 16 | $KIT_ARGS_BREADCRUMB 17 | ) 18 | 19 | # Emit the .kit file to be executed if kit_verbose is set 20 | # This prevents potentially dumping a sensitive file to a logfile 21 | if [ $${OM_KIT_VERBOSE:-0} = "1" ]; then 22 | export KIT_FILE=/app/apps/$KIT_FILE_NAME_BREADCRUMB 23 | echo "==== Print out kit config $${KIT_FILE} for debugging ====" 24 | cat $${KIT_FILE} 25 | echo "==== End of kit config $${KIT_FILE} ====" 26 | fi 27 | 28 | echo "Starting Kit with $$CMD $${ARGS[@]} $$@" 29 | 30 | # Chown the Kit caching directories to avoid permissions 31 | # issues between root and ubuntu user. 32 | chown -R ubuntu:ubuntu /home/ubuntu/.cache/ov 33 | chown -R ubuntu:ubuntu /home/ubuntu/.local/share/ov 34 | 35 | exec "$$CMD" "$${ARGS[@]}" "$$@" 36 | -------------------------------------------------------------------------------- /tools/isaacsim/data/python/linux-x86_64/icon/install_icon.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved. 2 | # 3 | # NVIDIA CORPORATION and its licensors retain all intellectual property 4 | # and proprietary rights in and to this software, related documentation 5 | # and any modifications thereto. Any use, reproduction, disclosure or 6 | # distribution of this software and related documentation without an express 7 | # license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | # 9 | 10 | import os 11 | import sys 12 | 13 | if sys.platform == "win32": 14 | pass 15 | else: 16 | icon_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "omni.isaac.sim.png") 17 | user_apps_folder = os.path.expanduser("~/.local/share/applications") 18 | if os.path.exists(user_apps_folder): 19 | with open(os.path.expanduser("~/.local/share/applications/IsaacSim.desktop"), "w") as file: 20 | print("Writing Isaac Sim icon file") 21 | file.write( 22 | f"""[Desktop Entry] 23 | Version=1.0 24 | Name=Isaac Sim 25 | Icon={icon_path} 26 | Terminal=false 27 | Type=Application 28 | StartupWMClass=IsaacSim""" 29 | ) 30 | -------------------------------------------------------------------------------- /tools/packman/python.bat: -------------------------------------------------------------------------------- 1 | :: Copyright 2019-2020 NVIDIA CORPORATION 2 | :: 3 | :: Licensed under the Apache License, Version 2.0 (the "License"); 4 | :: you may not use this file except in compliance with the License. 5 | :: You may obtain a copy of the License at 6 | :: 7 | :: http://www.apache.org/licenses/LICENSE-2.0 8 | :: 9 | :: Unless required by applicable law or agreed to in writing, software 10 | :: distributed under the License is distributed on an "AS IS" BASIS, 11 | :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | :: See the License for the specific language governing permissions and 13 | :: limitations under the License. 14 | 15 | @echo off 16 | setlocal enableextensions 17 | 18 | call "%~dp0\packman" init 19 | set "PYTHONPATH=%PM_MODULE_DIR%;%PYTHONPATH%" 20 | 21 | if not defined PYTHONNOUSERSITE ( 22 | set PYTHONNOUSERSITE=1 23 | ) 24 | 25 | REM For performance, default to unbuffered; however, allow overriding via 26 | REM PYTHONUNBUFFERED=0 since PYTHONUNBUFFERED on windows can truncate output 27 | REM when printing long strings 28 | if not defined PYTHONUNBUFFERED ( 29 | set PYTHONUNBUFFERED=1 30 | ) 31 | 32 | "%PM_PYTHON%" %* -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/python/impl/example_pybind_extension.py: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | ## 3 | ## NVIDIA CORPORATION and its licensors retain all intellectual property 4 | ## and proprietary rights in and to this software, related documentation 5 | ## and any modifications thereto. Any use, reproduction, disclosure or 6 | ## distribution of this software and related documentation without an express 7 | ## license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | ## 9 | import omni.ext 10 | from ..{{ library_name }} import * 11 | 12 | # Global public interface object. 13 | _bound_interface = None 14 | 15 | # Public API. 16 | def get_bound_interface() -> {{ interface_name }}: 17 | return _bound_interface 18 | 19 | 20 | # Use the extension entry points to acquire and release the interface. 21 | class ExamplePybindExtension(omni.ext.IExt): 22 | def __init__(self): 23 | super().__init__() 24 | 25 | global _bound_interface 26 | _bound_interface = acquire_bound_interface() 27 | 28 | def on_shutdown(self): 29 | global _bound_interface 30 | release_bound_interface(_bound_interface) 31 | _bound_interface = None 32 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/omni/example/cpp/pybind/{{object_interface_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace {{ extension_namespace }} 14 | { 15 | 16 | /** 17 | * Pure virtual bound object interface. 18 | */ 19 | class {{ object_interface_name }} : public carb::IObject 20 | { 21 | public: 22 | /** 23 | * Get the id of this object. 24 | * 25 | * @return Id of this object. 26 | */ 27 | virtual const char* getId() const = 0; 28 | }; 29 | 30 | /** 31 | * Implement the equality operator so these can be used in std containers. 32 | */ 33 | inline bool operator==(const carb::ObjectPtr<{{ object_interface_name }}>& left, 34 | const carb::ObjectPtr<{{ object_interface_name }}>& right) noexcept 35 | { 36 | return (left.get() == right.get()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/{{python_module_path}}/{{object_interface_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace {{ extension_namespace }} 14 | { 15 | 16 | /** 17 | * Pure virtual bound object interface. 18 | */ 19 | class {{ object_interface_name }} : public carb::IObject 20 | { 21 | public: 22 | /** 23 | * Get the id of this object. 24 | * 25 | * @return Id of this object. 26 | */ 27 | virtual const char* getId() const = 0; 28 | }; 29 | 30 | /** 31 | * Implement the equality operator so these can be used in std containers. 32 | */ 33 | inline bool operator==(const carb::ObjectPtr<{{ object_interface_name }}>& left, 34 | const carb::ObjectPtr<{{ object_interface_name }}>& right) noexcept 35 | { 36 | return (left.get() == right.get()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | name: Question 12 | description: Ask a question 13 | title: "[QUESTION]: " 14 | labels: ["question"] 15 | 16 | body: 17 | - type: markdown 18 | attributes: 19 | value: | 20 | Thanks for taking the time to ask us a question! 21 | 22 | - type: textarea 23 | id: text_of_question 24 | attributes: 25 | label: Question 26 | description: Ask your question. 27 | placeholder: "Question text" 28 | validations: 29 | required: true 30 | 31 | - type: textarea 32 | id: additional_context 33 | attributes: 34 | label: Additional Context 35 | description: Provide any related code, issues, or projects. 36 | placeholder: "Any related code, issues, or projects." 37 | -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/isaacsim.exp.template.ros2.kit: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ application_display_name }} ROS 2" 13 | version = "{{ version }}" 14 | description = "ROS2 enabled configuration of {{ application_display_name }}" 15 | keywords = ["experience", "app", "dev", "ros2"] 16 | template_name = "isaacsim.exp.template.ros2" 17 | 18 | [dependencies] 19 | "{{ application_name }}" = {} # Application Kit File 20 | "isaacsim.ros2.bridge" = {} 21 | 22 | [settings] 23 | app.vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows) 24 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 25 | 26 | [settings.app.exts.folders] 27 | '++' = [ 28 | "${app}", 29 | "${app}/../exts", 30 | "${app}/../extscache", 31 | ] -------------------------------------------------------------------------------- /tools/isaacsim/data/python/linux-x86_64/python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | error_exit() 6 | { 7 | echo "There was an error running python" 8 | exit 1 9 | } 10 | 11 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 12 | # MY_DIR="$(realpath -s "$SCRIPT_DIR")" 13 | 14 | # Setup python env from generated file (generated by tools/repoman/build.py) 15 | export CARB_APP_PATH=$SCRIPT_DIR/kit 16 | export ISAAC_PATH=$SCRIPT_DIR 17 | export EXP_PATH=$SCRIPT_DIR/apps 18 | source ${SCRIPT_DIR}/setup_python_env.sh 19 | 20 | # By default use our python, but allow overriding it by checking if PYTHONEXE env var is defined: 21 | python_exe=${PYTHONEXE:-"${SCRIPT_DIR}/kit/python/bin/python3"} 22 | 23 | 24 | if ! [[ -z "${CONDA_PREFIX}" ]]; then 25 | echo "Warning: running in conda env, please deactivate before executing this script" 26 | echo "If conda is desired please source setup_conda_env.sh in your python 3.10 conda env and run python normally" 27 | fi 28 | 29 | # Check if we are running in a docker container 30 | if [ -f /.dockerenv ]; then 31 | # Check for vulkan in docker container 32 | if [[ -f "${SCRIPT_DIR}/vulkan_check.sh" ]]; then 33 | ${SCRIPT_DIR}/vulkan_check.sh 34 | fi 35 | fi 36 | 37 | # Show icon if not running headless 38 | export RESOURCE_NAME="IsaacSim" 39 | # WAR for missing libcarb.so 40 | export LD_PRELOAD=$SCRIPT_DIR/kit/libcarb.so 41 | $python_exe "$@" $args || error_exit 42 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/omni/example/cpp/pybind/{{object_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include <{{ python_module_path }}/{{ object_interface_name }}.h> 12 | 13 | #include 14 | 15 | #include 16 | 17 | namespace {{ extension_namespace }} 18 | { 19 | 20 | /** 21 | * Helper base class for bound object implementations. 22 | */ 23 | class {{ object_name }} : public {{ object_interface_name }} 24 | { 25 | CARB_IOBJECT_IMPL 26 | 27 | public: 28 | /** 29 | * Constructor. 30 | * 31 | * @param id Id of the bound object. 32 | */ 33 | {{ object_name }}(const char* id) 34 | : m_id(id ? id : "") 35 | { 36 | } 37 | 38 | /** 39 | * @ref {{ object_interface_name }}::getId 40 | */ 41 | const char* getId() const override 42 | { 43 | return m_id.c_str(); 44 | } 45 | 46 | protected: 47 | const omni::string m_id; //!< Id of the bound object. 48 | }; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/{{python_module_path}}/{{object_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include <{{ python_module_path }}/{{ object_interface_name }}.h> 12 | 13 | #include 14 | 15 | #include 16 | 17 | namespace {{ extension_namespace }} 18 | { 19 | 20 | /** 21 | * Helper base class for bound object implementations. 22 | */ 23 | class {{ object_name }} : public {{ object_interface_name }} 24 | { 25 | CARB_IOBJECT_IMPL 26 | 27 | public: 28 | /** 29 | * Constructor. 30 | * 31 | * @param id Id of the bound object. 32 | */ 33 | {{ object_name }}(const char* id) 34 | : m_id(id ? id : "") 35 | { 36 | } 37 | 38 | /** 39 | * @ref {{ object_interface_name }}::getId 40 | */ 41 | const char* getId() const override 42 | { 43 | return m_id.c_str(); 44 | } 45 | 46 | protected: 47 | const omni::string m_id; //!< Id of the bound object. 48 | }; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tools/packman/python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019-2020 NVIDIA CORPORATION 4 | 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -e 18 | 19 | PACKMAN_CMD="$(dirname "${BASH_SOURCE}")/packman" 20 | if [ ! -f "$PACKMAN_CMD" ]; then 21 | PACKMAN_CMD="${PACKMAN_CMD}.sh" 22 | fi 23 | source "$PACKMAN_CMD" init 24 | export PYTHONPATH="${PM_MODULE_DIR}:${PYTHONPATH}" 25 | 26 | if [ -z "${PYTHONNOUSERSITE:-}" ]; then 27 | export PYTHONNOUSERSITE=1 28 | fi 29 | 30 | # For performance, default to unbuffered; however, allow overriding via 31 | # PYTHONUNBUFFERED=0 since PYTHONUNBUFFERED on windows can truncate output 32 | # when printing long strings 33 | if [ -z "${PYTHONUNBUFFERED:-}" ]; then 34 | export PYTHONUNBUFFERED=1 35 | fi 36 | 37 | # workaround for our python not shipping with certs 38 | if [[ -z ${SSL_CERT_DIR:-} ]]; then 39 | export SSL_CERT_DIR=/etc/ssl/certs/ 40 | fi 41 | 42 | "${PM_PYTHON}" "$@" 43 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/premake5.lua: -------------------------------------------------------------------------------- 1 | -- Setup the extension. 2 | local ext = get_current_extension_info() 3 | project_ext(ext) 4 | 5 | -- Link folders that should be packaged with the extension. 6 | repo_build.prebuild_link { 7 | { "data", ext.target_dir.."/data" }, 8 | { "docs", ext.target_dir.."/docs" }, 9 | } 10 | 11 | -- Build the C++ plugin that will be loaded by the extension. 12 | project_ext_plugin(ext, "{{ extension_name }}.plugin") 13 | add_files("include", "include/{{ python_module_path }}") 14 | add_files("source", "plugins/{{ extension_name }}") 15 | includedirs { "include", "plugins/{{ extension_name }}" } 16 | 17 | -- Build Python bindings that will be loaded by the extension. 18 | project_ext_bindings { 19 | ext = ext, 20 | project_name = "{{ extension_name }}.python", 21 | module = "{{ library_name }}", 22 | src = "bindings/python/{{ extension_name }}", 23 | target_subdir = "{{ python_module_path }}" 24 | } 25 | includedirs { "include" } 26 | repo_build.prebuild_link { 27 | { "python/impl", ext.target_dir.."/{{ python_module_path }}/impl" }, 28 | { "python/tests", ext.target_dir.."/{{ python_module_path }}/tests" }, 29 | } 30 | 31 | -- Build the C++ plugin that will be loaded by the tests. 32 | project_ext_tests(ext, "{{ extension_name }}.tests") 33 | add_files("source", "plugins/{{ extension_name }}.tests") 34 | includedirs { "include", "plugins/{{ extension_name }}.tests", "%{target_deps}/doctest/include" } 35 | -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/isaacsim.exp.template.zero_delay.kit: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ application_display_name }} Zero Delay" 13 | version = "{{ version }}" 14 | description = "Zero Delay configuration of {{ application_display_name }}" 15 | keywords = ["experience", "app", "dev", "zero_delay"] 16 | template_name = "isaacsim.exp.template.zero_delay" 17 | 18 | [dependencies] 19 | "{{ application_name }}" = {} # Application Kit File 20 | 21 | [settings] 22 | app.hydraEngine.waitIdle = true 23 | app.updateOrder.checkForHydraRenderComplete = 1000 24 | app.vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows) 25 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 26 | app.exts.isaacsim.ros2.bridge.publish_multithreading_disabled = true # disable multithreading for ros2 bridge to reduce latency 27 | 28 | [settings.app.exts.folders] 29 | '++' = [ 30 | "${app}", 31 | "${app}/../exts", 32 | "${app}/../extscache", 33 | ] -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/isaacsim.exp.template.fabric.kit: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ application_display_name }} Fabric" 13 | version = "{{ version }}" 14 | description = "Fabric configuration of {{ application_display_name }}" 15 | keywords = ["experience", "app", "dev", "fabric"] 16 | template_name = "isaacsim.exp.template.fabric" 17 | 18 | [dependencies] 19 | "{{ application_name }}" = {} # Application Kit File 20 | 21 | [settings] 22 | app.vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows) 23 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 24 | 25 | [settings.persistent] 26 | omnigraph.updateToUsd = false 27 | omnihydra.useFastSceneDelegate = true 28 | omnihydra.useSceneGraphInstancing = true 29 | physics.updateForceSensorsToUsd = false 30 | physics.visualizationDisplayJoints = false 31 | 32 | [settings.app.exts.folders] 33 | '++' = [ 34 | "${app}", 35 | "${app}/../exts", 36 | "${app}/../extscache", 37 | ] -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/isaacsim.exp.template.streaming.kit: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ application_display_name }} Streaming" 13 | version = "{{ version }}" 14 | description = "Streaming configuration of {{ application_display_name }}" 15 | keywords = ["experience", "app", "dev", "stremaing"] 16 | template_name = "isaacsim.exp.template.streaming" 17 | 18 | [dependencies] 19 | "{{ application_name }}" = {} # Application Kit File 20 | 21 | "omni.services.livestream.nvcf" = {} 22 | 23 | [settings] 24 | app.vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows) 25 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 26 | 27 | app.window.hideUi = false 28 | app.window.drawMouse = true 29 | app.window.enabled = false 30 | 31 | app.livestream.allowResize = false 32 | app.livestream.outDirectory = "${data}" 33 | 34 | [settings.app.exts.folders] 35 | '++' = [ 36 | "${app}", 37 | "${app}/../exts", 38 | "${app}/../extscache", 39 | ] -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | -- Shared build scripts from repo_build package. 2 | repo_build = require("omni/repo/build") 3 | 4 | -- Repo root 5 | root = repo_build.get_abs_path(".") 6 | 7 | -- Run repo_kit_tools premake5-kit that includes a bunch of Kit-friendly tooling configuration. 8 | kit = require("_repo/deps/repo_kit_tools/kit-template/premake5-kit") 9 | kit.setup_all({ cppdialect = "C++17" }) 10 | 11 | 12 | -- Registries config for testing 13 | repo_build.prebuild_copy { 14 | { "%{root}/tools/deps/user.toml", "%{root}/_build/deps/user.toml" }, 15 | } 16 | 17 | repo_build.prebuild_copy { 18 | {"tools/isaacsim/data/python/shared/*", "_build/%{platform}/%{config}"}, 19 | {"tools/isaacsim/data/python/%{platform}/*", "_build/%{platform}/%{config}"}, 20 | {"tools/isaacsim/data/jupyter_kernel", "_build/%{platform}/%{config}/jupyter_kernel"}, 21 | {"tools/isaacsim/data/python_packages", "_build/%{platform}/%{config}/python_packages" }, 22 | } 23 | -- Symlink extra files 24 | repo_build.prebuild_link { 25 | {"source/standalone_examples", "_build/%{platform}/%{config}/standalone_examples" }, 26 | } 27 | 28 | -- Isaac Sim default apps 29 | define_app("isaacsim.exp.base.kit") 30 | define_app("isaacsim.exp.base.xr.vr.kit") 31 | define_app("isaacsim.exp.base.zero_delay.kit") 32 | define_app("isaacsim.exp.full.fabric.kit") 33 | define_app("isaacsim.exp.full.kit") 34 | define_app("isaacsim.exp.full.streaming.kit", {extra_args = "--no-window"}) 35 | define_app("isaacsim.exp.action_and_event_data_generation.base.kit") 36 | define_app("isaacsim.exp.action_and_event_data_generation.full.kit") 37 | 38 | -------------------------------------------------------------------------------- /repo.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | :: Set OMNI_REPO_ROOT early so `repo` bootstrapping can target the repository 4 | :: root when writing out Python dependencies. 5 | :: Use SETLOCAL and ENDLOCAL to constrain these variables to this batch file. 6 | :: Use ENABLEDELAYEDEXPANSION to evaluate the value of PM_PACKAGES_ROOT 7 | :: at execution time. 8 | SETLOCAL ENABLEDELAYEDEXPANSION 9 | set OMNI_REPO_ROOT="%~dp0" 10 | 11 | :: Set Packman cache directory early if repo-cache.json is configured 12 | :: so that the Packman Python version is not fetched from the web. 13 | IF NOT EXIST "%~dp0repo-cache.json" goto :RepoCacheEnd 14 | 15 | :: Read PM_PACKAGES_ROOT from repo-cache.json and make sure it is an absolute path (assume relative to the script directory). 16 | for /f "usebackq tokens=*" %%i in (`powershell -NoProfile -Command "$PM_PACKAGES_ROOT = (Get-Content '%~dp0repo-cache.json' | ConvertFrom-Json).PM_PACKAGES_ROOT; if ([System.IO.Path]::IsPathRooted($PM_PACKAGES_ROOT)) { Write-Output ('absolute;' + $PM_PACKAGES_ROOT) } else { Write-Output ('relative;' + $PM_PACKAGES_ROOT) }"`) do ( 17 | for /f "tokens=1,2 delims=;" %%A in ("%%i") do ( 18 | if /i "%%A" == "relative" ( 19 | set PM_PACKAGES_ROOT=%~dp0%%B 20 | ) else ( 21 | set PM_PACKAGES_ROOT=%%B 22 | ) 23 | ) 24 | ) 25 | 26 | :RepoCacheEnd 27 | 28 | call "%~dp0tools\packman\python.bat" "%~dp0tools\repoman\repoman.py" %* 29 | if %errorlevel% neq 0 ( goto Error ) 30 | 31 | :Success 32 | ENDLOCAL 33 | exit /b 0 34 | 35 | :Error 36 | ENDLOCAL 37 | exit /b %errorlevel% 38 | -------------------------------------------------------------------------------- /tools/deps/kit-sdk-deps.packman.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tools/packman/bootstrap/fetch_file_from_packman_bootstrap.cmd: -------------------------------------------------------------------------------- 1 | :: Copyright 2019 NVIDIA CORPORATION 2 | :: 3 | :: Licensed under the Apache License, Version 2.0 (the "License"); 4 | :: you may not use this file except in compliance with the License. 5 | :: You may obtain a copy of the License at 6 | :: 7 | :: http://www.apache.org/licenses/LICENSE-2.0 8 | :: 9 | :: Unless required by applicable law or agreed to in writing, software 10 | :: distributed under the License is distributed on an "AS IS" BASIS, 11 | :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | :: See the License for the specific language governing permissions and 13 | :: limitations under the License. 14 | 15 | :: You need to specify as input to this command 16 | @setlocal 17 | @set PACKAGE_NAME=%1 18 | @set TARGET_PATH=%2 19 | 20 | @echo Fetching %PACKAGE_NAME% ... 21 | 22 | @powershell -ExecutionPolicy ByPass -NoLogo -NoProfile -File "%~dp0download_file_from_url.ps1" ^ 23 | -source "https://bootstrap.packman.nvidia.com/%PACKAGE_NAME%" -output %TARGET_PATH% 24 | :: A bug in powershell prevents the errorlevel code from being set when using the -File execution option 25 | :: We must therefore do our own failure analysis, basically make sure the file exists: 26 | @if not exist %TARGET_PATH% goto ERROR_DOWNLOAD_FAILED 27 | 28 | @endlocal 29 | @exit /b 0 30 | 31 | :ERROR_DOWNLOAD_FAILED 32 | @echo Failed to download file from S3 33 | @echo Most likely because endpoint cannot be reached or file %PACKAGE_NAME% doesn't exist 34 | @endlocal 35 | @exit /b 1 -------------------------------------------------------------------------------- /repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Set OMNI_REPO_ROOT early so `repo` bootstrapping can target the repository 6 | # root when writing out Python dependencies. 7 | export OMNI_REPO_ROOT="$( cd "$(dirname "$0")" ; pwd -P )" 8 | 9 | # By default custom caching is disabled in repo_man. But if a repo-cache.json 10 | # caching configuration file is generated via the `repo cache` command, it's 11 | # presence will trigger the configuration of custom caching. 12 | if [[ -f "${OMNI_REPO_ROOT}/repo-cache.json" ]]; then 13 | PM_PACKAGES_ROOT=$(grep '"PM_PACKAGES_ROOT"' "${OMNI_REPO_ROOT}/repo-cache.json" | sed 's/.*"PM_PACKAGES_ROOT": "\(.*\)".*/\1/') 14 | 15 | # PM_PACKAGES_ROOT is present in the config file. We set this early 16 | # so Packman will reference our cached package repository. 17 | if [[ -n "${PM_PACKAGES_ROOT}" ]]; then 18 | # Use eval to resolve ~ and perform parameter expansion 19 | RESOLVED_PACKAGES_ROOT=$(eval echo "$PM_PACKAGES_ROOT") 20 | 21 | if [[ "${RESOLVED_PACKAGES_ROOT}" != /* ]]; then 22 | # PM_PACKAGES_ROOT is not an abs path, assumption is then 23 | # that it is a relative path to the repository root. 24 | PM_PACKAGES_ROOT="${OMNI_REPO_ROOT}/${RESOLVED_PACKAGES_ROOT}" 25 | else 26 | PM_PACKAGES_ROOT=${RESOLVED_PACKAGES_ROOT} 27 | fi 28 | export PM_PACKAGES_ROOT 29 | fi 30 | fi 31 | 32 | # Use "exec" to ensure that environment variables don't accidentally affect other processes. 33 | exec "${OMNI_REPO_ROOT}/tools/packman/python.sh" "${OMNI_REPO_ROOT}/tools/repoman/repoman.py" "$@" 34 | -------------------------------------------------------------------------------- /tools/packman/bootstrap/download_file_from_url.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Copyright 2019 NVIDIA CORPORATION 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | #> 16 | 17 | param( 18 | [Parameter(Mandatory=$true)][string]$source=$null, 19 | [string]$output="out.exe" 20 | ) 21 | $filename = $output 22 | 23 | $triesLeft = 4 24 | $delay = 2 25 | do 26 | { 27 | $triesLeft -= 1 28 | 29 | try 30 | { 31 | Write-Host "Downloading from bootstrap.packman.nvidia.com ..." 32 | $wc = New-Object net.webclient 33 | $wc.Downloadfile($source, $fileName) 34 | exit 0 35 | } 36 | catch 37 | { 38 | Write-Host "Error downloading $source!" 39 | Write-Host $_.Exception|format-list -force 40 | if ($triesLeft) 41 | { 42 | Write-Host "Retrying in $delay seconds ..." 43 | Start-Sleep -seconds $delay 44 | } 45 | $delay = $delay * $delay 46 | } 47 | } while ($triesLeft -gt 0) 48 | # We only get here if the retries have been exhausted, remove any left-overs: 49 | if (Test-Path $fileName) 50 | { 51 | Remove-Item $fileName 52 | } 53 | exit 1 -------------------------------------------------------------------------------- /tools/deps/pip.toml: -------------------------------------------------------------------------------- 1 | ######################################################################################################################## 2 | # Example: 3 | ######################################################################################################################## 4 | 5 | # 6 | # [[dependency]] # Toml way to define array of objects. 7 | # python = "../../_build/target-deps/python" # Path to python used to install. Absolute or relative to this config. 8 | # packages = ["numpy"] # Array of packages to install, they all will be passed directly to pip. 9 | # target = "../../_build/target-deps/numpy" # Folder to install into. Absolute or relative to this config. 10 | # platforms = ["windows-x86_64"] # Platform(s) to filter, default is ["*"]. 11 | # download_only = true # Do pip download instead of install, gets a whl file that can be installed later. 12 | # 13 | 14 | # Another sample 15 | # [[dependency]] 16 | # python = "../../_build/target-deps/python" 17 | # packages = [ 18 | # "toml==0.10.1", 19 | # ] 20 | # target = "../../_build/target-deps/pip_prebundle" 21 | # platforms = ["*"] 22 | # download_only = false 23 | # append_to_install_folder = true 24 | # python_include_dir = true 25 | # subprocess_path = ["${root}/_build/host-deps/msvc/MSBuild/Current/Bin", "${root}/_build/host-deps/msvc/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64", "${root}/_build/host-deps/msvc/VC/Auxiliary/Build", "${root}/_build/host-deps/winsdk/bin/x64"] 26 | # msvc_path = "${root}/_build/host-deps/msvc/VC/Tools/MSVC/14.29.30133" 27 | # win_sdk_path = "${root}/_build/host-deps/winsdk" 28 | -------------------------------------------------------------------------------- /templates/apps/isaacsim_configs/isaacsim.exp.template.replicator.kit: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ application_display_name }} Replicator" 13 | version = "{{ version }}" 14 | description = "Replicator configuration of {{ application_display_name }}" 15 | keywords = ["experience", "app", "dev", "replicator"] 16 | template_name = "isaacsim.exp.template.replicator" 17 | 18 | [dependencies] 19 | "{{ application_name }}" = {} # Application Kit File 20 | "isaacsim.replicator.behavior" = {} 21 | "isaacsim.replicator.behavior.ui" = {} 22 | "isaacsim.replicator.domain_randomization" = {} 23 | "isaacsim.replicator.examples" = {} 24 | "isaacsim.replicator.scene_blox" = {} 25 | "isaacsim.replicator.synthetic_recorder" = {} 26 | "isaacsim.replicator.writers" = {} 27 | 28 | [settings] 29 | app.vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows) 30 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 31 | 32 | [settings.app.exts.folders] 33 | '++' = [ 34 | "${app}", 35 | "${app}/../exts", 36 | "${app}/../extscache", 37 | ] -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/config/extension.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | version = "1.0.1" # Semantic Versioning is used: https://semver.org/ 3 | 4 | # These fields are used primarily for display in the extension browser UI. 5 | title = "Example C++ Extension: pybind" 6 | description = "Demonstrates how to reflect C++ code using pybind11 so that it can be called from Python code." 7 | category = "Example" 8 | keywords = ["example", "C++", "cpp", "pybind"] 9 | icon = "data/icon.png" 10 | preview_image = "data/preview.png" 11 | changelog = "docs/CHANGELOG.md" 12 | readme = "docs/README.md" 13 | authors = ["David Bosnich "] 14 | repository = "https://github.com/NVIDIA-Omniverse/kit-extension-template-cpp" 15 | 16 | # Disable hot-reloading due to generated python bindings. 17 | [core] 18 | reloadable = false 19 | 20 | # Define the Python modules that this extension provides. 21 | [[python.module]] 22 | name = "{{ extension_name }}" 23 | 24 | # Define the C++ plugins that this extension provides. 25 | [[native.plugin]] 26 | path = "bin/*.plugin" 27 | 28 | # Define any test specific properties of this extension. 29 | [[test]] 30 | cppTests.libraries = [ 31 | "bin/${lib_prefix}{{ extension_name }}.tests${lib_ext}" 32 | ] 33 | 34 | # Define the documentation that will be generated for this extension. 35 | [documentation] 36 | pages = [ 37 | "docs/Overview.md", 38 | "docs/CHANGELOG.md", 39 | ] 40 | cpp_api = [ 41 | "include/{{ python_module_path }}/{{ interface_name }}.h", 42 | "include/{{ python_module_path }}/{{ object_interface_name }}.h", 43 | "include/{{ python_module_path }}/{{ object_name }}.h", 44 | ] 45 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/{{python_module_path}}/tests/test_hello.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | # NOTE: 12 | # omni.kit.test - std python's unittest module with additional wrapping to add support for async/await tests 13 | # For most things refer to unittest docs: https://docs.python.org/3/library/unittest.html 14 | # Import extension python module we are testing with absolute import path, as if we are an external user (other extension) 15 | import {{ python_module }} 16 | import omni.kit.test 17 | 18 | 19 | # Having a test class derived from omni.kit.test.AsyncTestCase declared on the root of the module 20 | # will make it auto-discoverable by omni.kit.test 21 | class Test(omni.kit.test.AsyncTestCaseFailOnLogError): 22 | # Before running each test 23 | async def setUp(self): 24 | pass 25 | 26 | # After running each test 27 | async def tearDown(self): 28 | pass 29 | 30 | # Actual test, notice it is an "async" function, so "await" can be used if needed 31 | async def test_hello_public_function(self): 32 | result = {{ python_module }}.some_public_function(4) 33 | self.assertEqual(result, 256) 34 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | NVIDIA is dedicated to the security and trust of our software products and services, including all source code repositories managed through our organization. 4 | 5 | If you need to report a security issue, please use the appropriate contact points outlined below. **Please do not report security vulnerabilities through GitHub/GitLab.** 6 | 7 | ## Reporting Potential Security Vulnerability in an NVIDIA Product 8 | 9 | To report a potential security vulnerability in any NVIDIA product: 10 | - Web: [Security Vulnerability Submission Form](https://www.nvidia.com/object/submit-security-vulnerability.html) 11 | - E-Mail: psirt@nvidia.com 12 | - We encourage you to use the following PGP key for secure email communication: [NVIDIA public PGP Key for communication](https://www.nvidia.com/en-us/security/pgp-key) 13 | - Please include the following information: 14 | - Product/Driver name and version/branch that contains the vulnerability 15 | - Type of vulnerability (code execution, denial of service, buffer overflow, etc.) 16 | - Instructions to reproduce the vulnerability 17 | - Proof-of-concept or exploit code 18 | - Potential impact of the vulnerability, including how an attacker could exploit the vulnerability 19 | 20 | While NVIDIA currently does not have a bug bounty program, we do offer acknowledgement when an externally reported security issue is addressed under our coordinated vulnerability disclosure policy. Please visit our [Product Security Incident Response Team (PSIRT)](https://www.nvidia.com/en-us/security/psirt-policies/) policies page for more information. 21 | 22 | ## NVIDIA Product Security 23 | 24 | For all security-related concerns, please visit NVIDIA's Product Security portal at https://www.nvidia.com/en-us/security 25 | -------------------------------------------------------------------------------- /tools/repoman/repoman.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | 5 | import contextlib 6 | import io 7 | import json 8 | import os 9 | import sys 10 | import warnings 11 | from pathlib import Path 12 | 13 | import packmanapi 14 | from repoman_bootstrapper import repoman_bootstrap 15 | 16 | REPO_ROOT = os.path.join(os.path.dirname(os.path.normpath(__file__)), "../..") 17 | REPO_DEPS_FILE = Path(REPO_ROOT) / "tools/deps/repo-deps.packman.xml" 18 | OPT_DEPS_FILE = Path(REPO_ROOT) / "tools/deps/repo-deps-nv.packman.xml" 19 | REPO_CACHE_FILE = os.path.join(REPO_ROOT, "repo-cache.json") 20 | 21 | 22 | def bootstrap(): 23 | """ 24 | Bootstrap all omni.repo modules. 25 | 26 | Pull with packman from repo.packman.xml and add them all to python sys.path to enable importing. 27 | """ 28 | with contextlib.redirect_stdout(io.StringIO()): 29 | for file in [REPO_DEPS_FILE, OPT_DEPS_FILE]: 30 | if file.is_file(): 31 | deps = packmanapi.pull(file.as_posix()) 32 | 33 | for dep_path in deps.values(): 34 | if dep_path not in sys.path: 35 | sys.path.append(dep_path) 36 | 37 | 38 | if __name__ == "__main__": 39 | repoman_bootstrap() 40 | bootstrap() 41 | 42 | with warnings.catch_warnings(record=True): 43 | # Ignore repo_changelog missing warnings associated with 44 | # repo_kit_tools. repo_kit_tools will warn if changelog is missing 45 | # but we do not use changelog functionality in kit-app-template. 46 | warnings.filterwarnings("ignore", message=r".*repo_changelog.*") 47 | import omni.repo.man 48 | 49 | omni.repo.man.main(REPO_ROOT) 50 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/{{python_module_path}}/{{interface_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include <{{ python_module_path }}/{{ object_interface_name }}.h> 12 | 13 | #include 14 | 15 | namespace {{ extension_namespace }} 16 | { 17 | 18 | /** 19 | * An example interface to demonstrate reflection using pybind. 20 | */ 21 | class {{ interface_name }} 22 | { 23 | public: 24 | /// @private 25 | CARB_PLUGIN_INTERFACE("{{ extension_namespace }}::{{ interface_name }}", 1, 0); 26 | 27 | /** 28 | * Register a bound object. 29 | * 30 | * @param object The bound object to register. 31 | */ 32 | virtual void register{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) = 0; 33 | 34 | /** 35 | * Deregister a bound object. 36 | * 37 | * @param object The bound object to deregister. 38 | */ 39 | virtual void deregister{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) = 0; 40 | 41 | /** 42 | * Find a bound object. 43 | * 44 | * @param id Id of the bound object. 45 | * 46 | * @return The bound object if it exists, an empty ObjectPtr otherwise. 47 | */ 48 | virtual carb::ObjectPtr<{{ object_interface_name }}> find{{object_name}}(const char* id) const = 0; 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/include/omni/example/cpp/pybind/{{interface_name}}.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | #pragma once 10 | 11 | #include <{{ python_module_path }}/{{ object_interface_name }}.h> 12 | 13 | #include 14 | 15 | namespace {{ extension_namespace }} 16 | { 17 | 18 | /** 19 | * An example interface to demonstrate reflection using pybind. 20 | */ 21 | class {{ interface_name }} 22 | { 23 | public: 24 | /// @private 25 | CARB_PLUGIN_INTERFACE("{{ extension_namespace }}::{{ interface_name }}", 1, 0); 26 | 27 | /** 28 | * Register a bound object. 29 | * 30 | * @param object The bound object to register. 31 | */ 32 | virtual void register{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) = 0; 33 | 34 | /** 35 | * Deregister a bound object. 36 | * 37 | * @param object The bound object to deregister. 38 | */ 39 | virtual void deregister{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) = 0; 40 | 41 | /** 42 | * Find a bound object. 43 | * 44 | * @param id Id of the bound object. 45 | * 46 | * @return The bound object if it exists, an empty ObjectPtr otherwise. 47 | */ 48 | virtual carb::ObjectPtr<{{ object_interface_name }}> find{{object_name}}(const char* id) const = 0; 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/config/extension.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ extension_display_name }}" 13 | version = "{{ version }}" # Semantic Versioning is used: https://semver.org/ 14 | description = "Simple example of an extension that loads a C++ plugin." 15 | category = "Example" # How to categorize this in the Extension Manager 16 | changelog = "docs/CHANGELOG.md" 17 | icon = "data/icon.png" # Icon to show in the Extension Manager 18 | keywords = ["kit", "example", "extension"] # Search keywords for the Extension Manager 19 | preview_image = "data/preview.png" # Preview to show in the Extension Manager 20 | readme = "docs/README.md" # Path (relative to the root) or content of readme markdown file for UI 21 | repository = "https://github.com/NVIDIA-Omniverse/kit-app-template" # URL of the extension source repository 22 | 23 | 24 | [dependencies] 25 | 26 | 27 | [settings] 28 | 29 | [[native.plugin]] 30 | path = "bin/*.plugin" 31 | recursive = false 32 | 33 | 34 | [documentation] 35 | pages = [ 36 | "docs/Overview.md", 37 | "docs/CHANGELOG.md", 38 | ] 39 | 40 | 41 | [[test]] 42 | dependencies = [ 43 | ] 44 | 45 | args =[ 46 | ] 47 | 48 | cppTests.libraries = [ 49 | # "bin/${lib_prefix}{{ extension_name }}.tests${lib_ext}", 50 | ] -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/config/extension.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ extension_display_name }}" 13 | version = "{{ version }}" # Semantic Versioning is used: https://semver.org/ 14 | description = "The simplest python extension example. Use it as a starting point for your extensions." 15 | category = "Example" # How to categorize this in the Extension Manager 16 | changelog = "docs/CHANGELOG.md" 17 | icon = "data/icon.png" # Icon to show in the Extension Manager 18 | keywords = ["kit", "example", "extension"] # Search keywords for the Extension Manager 19 | preview_image = "data/preview.png" # Preview to show in the Extension Manager 20 | readme = "docs/README.md" # Path (relative to the root) or content of readme markdown file for UI 21 | repository = "https://github.com/NVIDIA-Omniverse/kit-app-template" # URL of the extension source repository 22 | 23 | 24 | [dependencies] 25 | 26 | 27 | [settings] 28 | 29 | 30 | [[python.module]] # Main python module this extension provides, it will be publicly available as "import {{python_module}}" 31 | name = "{{ extension_name }}" 32 | 33 | 34 | [documentation] 35 | pages = [ 36 | "docs/Overview.md", 37 | "docs/CHANGELOG.md", 38 | ] 39 | 40 | 41 | [[test]] 42 | dependencies = [ 43 | ] 44 | 45 | args = [ 46 | ] -------------------------------------------------------------------------------- /tools/containers/entrypoint.sh.j2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -u 4 | 5 | write_omniverse_toml() { 6 | # Write out an omniverse.toml configuration file for Kit that contains a bookmark 7 | # for a custom provided nucleus server. 8 | local bookmark_name=$$1 9 | local bookmark_value=$$2 10 | mkdir --parents /home/ubuntu/.nvidia-omniverse/config 11 | cat < /home/ubuntu/.nvidia-omniverse/config/omniverse.toml 12 | [bookmarks] 13 | "$${bookmark_name}" = "$${bookmark_value}" 14 | EOF 15 | } 16 | 17 | 18 | USER_ID="$${USER_ID:-""}" 19 | if [ -z "$${USER_ID}" ]; then 20 | echo "User id is not set" 21 | fi 22 | 23 | # if NVDA_KIT_NUCLEUS is set, write out the omniverse.toml value 24 | if [ -n "$${NVDA_KIT_NUCLEUS:-}" ]; then 25 | write_omniverse_toml "$${NVDA_KIT_BOOKMARK_NAME:-$${NVDA_KIT_NUCLEUS}}" "$${NVDA_KIT_BOOKMARK_VALUE:-omniverse://$${NVDA_KIT_NUCLEUS}}" 26 | # Additionally set the Nucleus server address to the provided address. 27 | nucleus_cmd="--/ovc/nucleus/server=$${NVDA_KIT_NUCLEUS}" 28 | fi 29 | 30 | CMD="/app/kit/kit" 31 | ARGS=( 32 | "/app/apps/$KIT_FILE_NAME_BREADCRUMB" 33 | $KIT_ARGS_BREADCRUMB 34 | $${NVDA_KIT_ARGS:-""} 35 | $${nucleus_cmd:-""} 36 | ) 37 | 38 | # Emit the .kit file to be executed if kit_verbose is set 39 | # This prevents potentially dumping a sensitive file to a logfile 40 | if [ $${OM_KIT_VERBOSE:-0} = "1" ]; then 41 | export KIT_FILE=/app/apps/$KIT_FILE_NAME_BREADCRUMB 42 | echo "==== Print out kit config $${KIT_FILE} for debugging ====" 43 | cat $${KIT_FILE} 44 | echo "==== End of kit config $${KIT_FILE} ====" 45 | fi 46 | 47 | echo "Starting Kit with $$CMD $${ARGS[@]} $$@" 48 | 49 | # Chown the Kit caching directories to avoid permissions 50 | # issues between root and ubuntu user. 51 | chown -R ubuntu:ubuntu /home/ubuntu/.cache/ov 52 | chown -R ubuntu:ubuntu /home/ubuntu/.local/share/ov 53 | 54 | eval "$$CMD" "$${ARGS[@]}" "$$@" 55 | -------------------------------------------------------------------------------- /readme-assets/additional-docs/data_collection_and_use.md: -------------------------------------------------------------------------------- 1 | # Data Collection & Use 2 | 3 | 4 | ## Overview 5 | 6 | 7 | NVIDIA Omniverse Kit Application Template collects anonymous usage data to help improve software performance and aid in diagnostic purposes. Rest assured, no personal information such as user email, name or any other PII field is collected. 8 | 9 | 10 | ## Purpose 11 | 12 | 13 | Omniverse Kit Application Template starts collecting data when you begin interaction with our provided software. 14 | It includes:- 15 | - Installation and configuration details such as version of operating system, applications installed : Allows us to recognize usage trends & patterns 16 | - Hardware Details such as CPU, GPU, monitor information : Allows us to optimize settings in order to provide best performance 17 | - Product session and feature usage : Allows us to understand user journey and product interaction to further enhance workflows 18 | Error and crash logs : Allows us to improve performance & stability for troubleshooting and diagnostic purposes of our software 19 | 20 | 21 | 22 | 23 | ## Turn off Data Collection 24 | 25 | 26 | To turn off data collection, you must need to change a setting: 27 | 28 | 29 | 1. After creating an application with the `template new` tooling, go to the `source/apps` directory 30 | 2. Locate the `.kit` file for the application you want to disable telemetry for. 31 | 3. Find the following section in the `.kit` file: 32 | 33 | 34 | ```toml 35 | [settings.telemetry] 36 | # Anonymous Kit application usage telemetry 37 | enableAnonymousData = true 38 | ``` 39 | 4. Change `enableAnonymousData` to `false`: 40 | 41 | 42 | ```toml 43 | [settings.telemetry] 44 | # Anonymous Kit application usage telemetry 45 | enableAnonymousData = false 46 | ``` 47 | 48 | 49 | Disabling telemetry stops data collection from your application. 50 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/config/extension.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | [package] 12 | title = "{{ extension_display_name }}" 13 | version = "{{ version }}" # Semantic Versioning is used: https://semver.org/ 14 | description = "The simplest python UI extension example. Use it as a starting point for your extensions." 15 | category = "Example" # How to categorize this in the Extension Manager 16 | changelog = "docs/CHANGELOG.md" 17 | icon = "data/icon.png" # Icon to show in the Extension Manager 18 | keywords = ["kit", "example", "extension", "python", "ui"] # Search keywords for the Extension Manager 19 | preview_image = "data/preview.png" # Preview to show in the Extension Manager 20 | readme = "docs/README.md" # Path (relative to the root) or content of readme markdown file for UI 21 | repository = "https://github.com/NVIDIA-Omniverse/kit-app-template" # URL of the extension source repository 22 | 23 | 24 | [dependencies] 25 | "omni.kit.uiapp" = {} 26 | 27 | 28 | [settings] 29 | 30 | 31 | [[python.module]] # Main python module this extension provides, it will be publicly available as "import {{python_module}}" 32 | name = "{{ extension_name }}" 33 | 34 | 35 | [documentation] 36 | pages = [ 37 | "docs/Overview.md", 38 | "docs/CHANGELOG.md", 39 | ] 40 | 41 | 42 | [[test]] 43 | dependencies = [ 44 | "omni.kit.test", 45 | "omni.kit.ui_test" # UI testing extension 46 | ] 47 | 48 | args = [ 49 | ] 50 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/{{python_module_path}}/extension.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. 2 | # All rights reserved. 3 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 4 | # 5 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 6 | # property and proprietary rights in and to this material, related 7 | # documentation and any modifications thereto. Any use, reproduction, 8 | # disclosure or distribution of this material and related documentation 9 | # without an express license agreement from NVIDIA CORPORATION or 10 | # its affiliates is strictly prohibited. 11 | 12 | import omni.ext 13 | 14 | 15 | # Functions and vars are available to other extensions as usual in python: 16 | # `{{python_module}}.some_public_function(x)` 17 | def some_public_function(x: int): 18 | """This is a public function that can be called from other extensions.""" 19 | print(f"[{{ extension_name }}] some_public_function was called with {x}") 20 | return x**x 21 | 22 | 23 | # Any class derived from `omni.ext.IExt` in the top level module (defined in 24 | # `python.modules` of `extension.toml`) will be instantiated when the extension 25 | # gets enabled, and `on_startup(ext_id)` will be called. Later when the 26 | # extension gets disabled on_shutdown() is called. 27 | class MyExtension(omni.ext.IExt): 28 | """This is a blank extension template.""" 29 | # ext_id is the current extension id. It can be used with the extension 30 | # manager to query additional information, like where this extension is 31 | # located on the filesystem. 32 | def on_startup(self, _ext_id): 33 | """This is called every time the extension is activated.""" 34 | print("[{{ extension_name }}] Extension startup") 35 | 36 | def on_shutdown(self): 37 | """This is called every time the extension is deactivated. It is used 38 | to clean up the extension state.""" 39 | print("[{{ extension_name }}] Extension shutdown") 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | name: Feature Request 12 | description: Suggest an idea for this project 13 | title: "[FEATURE]: " 14 | labels: ["feature request"] 15 | 16 | body: 17 | - type: markdown 18 | attributes: 19 | value: | 20 | Thanks for taking the time to help Kit App Template and fill out this feature request! 21 | 22 | - type: textarea 23 | id: description 24 | attributes: 25 | label: Description 26 | description: | 27 | Describe the proposed feature 28 | placeholder: | 29 | Feature description and problem or pain point being addressed 30 | 31 | validations: 32 | required: true 33 | 34 | - type: textarea 35 | id: use_case 36 | attributes: 37 | label: Use Case or Scenarios 38 | description: Describe how this feature would be used 39 | placeholder: e.g., User performing action A, would accomplish B, with benefit C. 40 | 41 | - type: textarea 42 | id: implementation_ideas 43 | attributes: 44 | label: Possible Implementation Ideas 45 | description: If you have any suggestions on how this feature might be implemented, please share them here. 46 | placeholder: Implementation ideas 47 | 48 | 49 | - type: textarea 50 | id: additional_context 51 | attributes: 52 | label: Additional Context or Recommendations 53 | description: Provide any other context or recommendations here. 54 | placeholder: Any other relevant information. 55 | -------------------------------------------------------------------------------- /tools/containers/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # This Dockerfile is used as the base for containerizing applications rendered out via repo_kit_template. 2 | 3 | # This is the base image for the container. It is based on Ubuntu 22.04. 4 | FROM nvcr.io/nvidia/omniverse/ov-base-ubuntu-22:2025.2.0 5 | 6 | # root user to bootstrap the container 7 | USER root 8 | # install curl 9 | RUN apt update \ 10 | && DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ 11 | curl \ 12 | && apt -y autoremove \ 13 | && apt clean autoclean \ 14 | && rm -rf /var/lib/apt/lists/* 15 | 16 | # Create local user 17 | RUN useradd --create-home --shell /bin/bash ubuntu || echo "User already exists." 18 | # Create the 'ubuntu' user and add it to the 'sudo' group 19 | RUN usermod -aG sudo ubuntu 20 | # nopasswd sudo 21 | RUN mkdir -p /etc/sudoers.d/ 22 | RUN echo "ubuntu ALL=(ALL:ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/ubuntu 23 | 24 | # Copy the staged fat package into the /app directory 25 | COPY --chown=root:root --chmod=555 package /app/ 26 | 27 | USER ubuntu 28 | WORKDIR /app 29 | 30 | # Copy the container entrypoint script 31 | COPY --chown=root:root --chmod=555 entrypoint.sh /entrypoint.sh 32 | 33 | # Create Kit expected caching directories that we'll map a volume onto. 34 | RUN mkdir -p /home/ubuntu/.cache/ov 35 | RUN mkdir -p /home/ubuntu/.local/share/ov 36 | RUN mkdir -p /home/ubuntu/.nvidia-omniverse/config 37 | 38 | # Create StreamSDK extended timeout config file 39 | RUN mkdir -p /home/ubuntu/.config 40 | COPY --chown=root:root --chmod=555 stream_sdk.txt /home/ubuntu/.config/regkeys.txt 41 | 42 | # Label for discovering kit_app_template built images within the docker registry. 43 | LABEL kit_app_template=$KIT_FILE_NAME_BREADCRUMB 44 | 45 | # Open ports for live streaming 46 | EXPOSE 47995-48012/udp \ 47 | 47995-48012/tcp \ 48 | 49000-49007/udp \ 49 | 49000-49007/tcp \ 50 | 8011/tcp \ 51 | 8111/tcp \ 52 | 49100/tcp 53 | 54 | # This specifies the container's default entrypoint that will be called by "> docker run". 55 | ENTRYPOINT [ "/entrypoint.sh" ] -------------------------------------------------------------------------------- /tools/isaacsim/data/python/linux-x86_64/jupyter_notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | error_exit() 6 | { 7 | echo "There was an error running Jupyter Notebook" 8 | exit 1 9 | } 10 | 11 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 12 | # MY_DIR="$(realpath -s "$SCRIPT_DIR")" 13 | printf "SCRIPT_DIR = %s\n" $SCRIPT_DIR 14 | # Setup python env from generated file (generated by tools/repoman/build.py) 15 | export CARB_APP_PATH=$SCRIPT_DIR/kit 16 | export ISAAC_PATH=$SCRIPT_DIR 17 | export EXP_PATH=$SCRIPT_DIR/apps 18 | # Set the path so it sees the python3 that kit uses first. 19 | export PATH=$SCRIPT_DIR/kit/python/bin:$PATH 20 | source ${SCRIPT_DIR}/setup_python_env.sh 21 | python_exe=${SCRIPT_DIR}/kit/python/bin/python3 22 | printf "Performing setup...\n" 23 | # install jupyter as a dependency so the env supports running notebooks 24 | ${python_exe} -m pip install --upgrade --upgrade-strategy only-if-needed jupyter 25 | printf "Setup complete\n" 26 | #runtime configure kernelspec based on current python exe path 27 | kernel_dir=$(mktemp -d) 28 | cp -r ${SCRIPT_DIR}/jupyter_kernel ${kernel_dir} 29 | sed -i 's,AUTOMATICALLY_REPLACED,'"${python_exe}"',' ${kernel_dir}/jupyter_kernel/kernel.json 30 | 31 | # Add the kernelspec to jupyter notebook 32 | jupyter kernelspec install ${kernel_dir}/jupyter_kernel --name isaac_sim_python3 --user 33 | 34 | # Remove temp dir for kernel once installed 35 | rm -rf ${kernel_dir} 36 | 37 | # Check if we are running in a docker container 38 | if [ -f /.dockerenv ]; then 39 | # Check for vulkan in docker container 40 | if [[ -f "${SCRIPT_DIR}/vulkan_check.sh" ]]; then 41 | ${SCRIPT_DIR}/vulkan_check.sh 42 | fi 43 | fi 44 | 45 | # if the user provides the argument test as the first argument, 46 | # we attempt to run the notebook in place via commandline and exit 47 | if [[ $1 == test ]]; then 48 | shift 49 | jupyter nbconvert --ExecutePreprocessor.timeout=600 --ExecutePreprocessor.kernel_name="isaac_sim_python3" --to notebook --execute --output=/tmp/isaac_test.ipynb $@ || error_exit 50 | else 51 | jupyter notebook --MappingKernelManager.default_kernel_name="Isaac Sim Python 3" $@ || error_exit 52 | fi 53 | 54 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/plugins/{{extension_name}}/ExamplePybindExtension.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | 10 | #define CARB_EXPORTS 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include <{{ python_module_path }}/{{ interface_name }}.h> 17 | 18 | #include 19 | 20 | const struct carb::PluginImplDesc pluginImplDesc = { "{{ extension_name }}.plugin", 21 | "An example C++ extension.", "NVIDIA", 22 | carb::PluginHotReload::eEnabled, "dev" }; 23 | 24 | namespace {{ extension_namespace }} 25 | { 26 | 27 | class ExampleBoundImplementation : public {{ interface_name }} 28 | { 29 | public: 30 | void register{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) override 31 | { 32 | if (object) 33 | { 34 | m_registeredObjectsById[object->getId()] = object; 35 | } 36 | } 37 | 38 | void deregister{{object_name}}(carb::ObjectPtr<{{ object_interface_name }}>& object) override 39 | { 40 | if (object) 41 | { 42 | const auto& it = m_registeredObjectsById.find(object->getId()); 43 | if (it != m_registeredObjectsById.end()) 44 | { 45 | m_registeredObjectsById.erase(it); 46 | } 47 | } 48 | } 49 | 50 | carb::ObjectPtr<{{ object_interface_name }}> find{{object_name}}(const char* id) const override 51 | { 52 | const auto& it = m_registeredObjectsById.find(id); 53 | if (it != m_registeredObjectsById.end()) 54 | { 55 | return it->second; 56 | } 57 | 58 | return carb::ObjectPtr<{{ object_interface_name }}>(); 59 | } 60 | 61 | private: 62 | std::unordered_map> m_registeredObjectsById; 63 | }; 64 | 65 | } 66 | 67 | CARB_PLUGIN_IMPL(pluginImplDesc, {{ extension_namespace }}::ExampleBoundImplementation) 68 | 69 | void fillInterface({{ extension_namespace }}::ExampleBoundImplementation& iface) 70 | { 71 | } 72 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/{{python_module_path}}/tests/test_hello_world.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | # NOTE: 12 | # omni.kit.test - std python's unittest module with additional wrapping to add 13 | # suport for async/await tests 14 | # For most things refer to unittest docs: 15 | # https://docs.python.org/3/library/unittest.html 16 | import omni.kit.test 17 | 18 | # Extension for writing UI tests (to simulate UI interaction) 19 | import omni.kit.ui_test as ui_test 20 | 21 | # Import extension python module we are testing with absolute import path, 22 | # as if we are external user (other extension) 23 | import {{ python_module }} 24 | 25 | 26 | # Having a test class dervived from omni.kit.test.AsyncTestCase declared on the 27 | # root of module will make it auto-discoverable by omni.kit.test 28 | class Test(omni.kit.test.AsyncTestCase): 29 | # Before running each test 30 | async def setUp(self): 31 | pass 32 | 33 | # After running each test 34 | async def tearDown(self): 35 | pass 36 | 37 | # Actual test, notice it is an "async" function, so "await" can be used if needed 38 | async def test_hello_public_function(self): 39 | result = {{ python_module }}.some_public_function(4) 40 | self.assertEqual(result, 256) 41 | 42 | async def test_window_button(self): 43 | # Find a label in our window 44 | label = ui_test.find("{{ extension_display_name }}//Frame/**/Label[*]") 45 | 46 | # Find buttons in our window 47 | add_button = ui_test.find( 48 | "{{ extension_display_name }}//Frame/**/Button[*].text=='Add'" 49 | ) 50 | reset_button = ui_test.find( 51 | "{{ extension_display_name }}//Frame/**/Button[*].text=='Reset'" 52 | ) 53 | 54 | # Click reset button 55 | await reset_button.click() 56 | self.assertEqual(label.widget.text, "empty") 57 | 58 | await add_button.click() 59 | self.assertEqual(label.widget.text, "count: 1") 60 | 61 | await add_button.click() 62 | self.assertEqual(label.widget.text, "count: 2") 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | name: Bug Report 12 | description: File a bug report for the repository 13 | title: "[BUG]: " 14 | labels: ["bug"] 15 | 16 | body: 17 | - type: markdown 18 | attributes: 19 | value: | 20 | Thanks for taking the time to help Kit App Template and fill out this bug report! 21 | 22 | - type: textarea 23 | id: description 24 | attributes: 25 | label: Description 26 | description: | 27 | Describe the bug in detail 28 | placeholder: | 29 | Expected Behavior vs. Actual Behavior: 30 | validations: 31 | required: true 32 | 33 | - type: textarea 34 | id: component 35 | attributes: 36 | label: Component 37 | description: Which component (Tool/Template/Extension) is showing the bug? 38 | placeholder: "e.g., Kit Base Editor Template / repo launch tool / Kit SDK" 39 | 40 | - type: textarea 41 | id: system-details 42 | attributes: 43 | label: System Details 44 | description: | 45 | Provide details about your system 46 | placeholder: | 47 | OS / CPU / GPU / GPU Driver Version 48 | validations: 49 | required: true 50 | 51 | - type: textarea 52 | id: reproduction-steps 53 | attributes: 54 | label: Reproduction Steps 55 | description: What are the steps to reproduce the bug? 56 | placeholder: | 57 | 1. Step 1... 58 | 59 | validations: 60 | required: true 61 | 62 | - type: textarea 63 | id: logs 64 | attributes: 65 | label: Logs 66 | description: | 67 | Include the relevant log files: 68 | - **repo.log:** Found in `_repo/repo.log` if the issue is with tooling. 69 | - **kit.log:** Found in `_build/{OS}/release/logs/.../kit_{...}log` if the issue is with App, Extension, or Kit SDK. 70 | placeholder: Paste the log content here or attach the log files. 71 | 72 | - type: textarea 73 | id: additional-context 74 | attributes: 75 | label: Additional Context 76 | description: Provide any other context or information here. 77 | placeholder: Any other information that might be helpful -------------------------------------------------------------------------------- /templates/extensions/python_ui/template/{{python_module_path}}/extension.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 3 | # 4 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 5 | # property and proprietary rights in and to this material, related 6 | # documentation and any modifications thereto. Any use, reproduction, 7 | # disclosure or distribution of this material and related documentation 8 | # without an express license agreement from NVIDIA CORPORATION or 9 | # its affiliates is strictly prohibited. 10 | 11 | import omni.ext 12 | import omni.ui as ui 13 | 14 | 15 | # Functions and vars are available to other extensions as usual in python: 16 | # `{{python_module}}.some_public_function(x)` 17 | def some_public_function(x: int): 18 | """This is a public function that can be called from other extensions.""" 19 | print(f"[{{ extension_name }}] some_public_function was called with {x}") 20 | return x ** x 21 | 22 | 23 | # Any class derived from `omni.ext.IExt` in the top level module (defined in 24 | # `python.modules` of `extension.toml`) will be instantiated when the extension 25 | # gets enabled, and `on_startup(ext_id)` will be called. Later when the 26 | # extension gets disabled on_shutdown() is called. 27 | class MyExtension(omni.ext.IExt): 28 | """This extension manages a simple counter UI.""" 29 | # ext_id is the current extension id. It can be used with the extension 30 | # manager to query additional information, like where this extension is 31 | # located on the filesystem. 32 | def on_startup(self, _ext_id): 33 | """This is called every time the extension is activated.""" 34 | print("[{{ extension_name }}] Extension startup") 35 | 36 | self._count = 0 37 | self._window = ui.Window( 38 | "{{ extension_display_name }}", width=300, height=300 39 | ) 40 | with self._window.frame: 41 | with ui.VStack(): 42 | label = ui.Label("") 43 | 44 | def on_click(): 45 | self._count += 1 46 | label.text = f"count: {self._count}" 47 | 48 | def on_reset(): 49 | self._count = 0 50 | label.text = "empty" 51 | 52 | on_reset() 53 | 54 | with ui.HStack(): 55 | ui.Button("Add", clicked_fn=on_click) 56 | ui.Button("Reset", clicked_fn=on_reset) 57 | 58 | def on_shutdown(self): 59 | """This is called every time the extension is deactivated. It is used 60 | to clean up the extension state.""" 61 | print("[{{ extension_name }}] Extension shutdown") 62 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/template/{{python_module_path}}/tests/test_benchmarks.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. 2 | # All rights reserved. 3 | # SPDX-License-Identifier: LicenseRef-NvidiaProprietary 4 | # 5 | # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 6 | # property and proprietary rights in and to this material, related 7 | # documentation and any modifications thereto. Any use, reproduction, 8 | # disclosure or distribution of this material and related documentation 9 | # without an express license agreement from NVIDIA CORPORATION or 10 | # its affiliates is strictly prohibited. 11 | 12 | import asyncio 13 | 14 | from omni.kit.test import AsyncTestCase, BenchmarkTestCase 15 | 16 | 17 | class TestBenchmarks(BenchmarkTestCase): 18 | """ 19 | Example Benchmark class with custom metrics. 20 | * To use custom metrics one has to derive from `BenchmarkTestCase`. 21 | * Benchmark methods have to start with the 'benchmark' prefix. 22 | * The runtime of the benchmark methods and their skip state 23 | belong to the default metrics which are always reported. 24 | """ 25 | 26 | def setUp(self): 27 | pass 28 | 29 | async def benchmark_sleepy_with_custom_metrics(self): 30 | """ 31 | Benchmark method using custom metrics. 32 | """ 33 | # sample for custom metric 'sleep_time' is set to 0.1s 34 | self.set_metric_sample(name="sleep_time", value=0.1, unit="s") 35 | await asyncio.sleep(0.1) 36 | # sample for custom metric 'runs' is set to 1 37 | self.set_metric_sample(name="runs", value=1) 38 | 39 | async def benchmark_sleepy_with_custom_metrics_array(self): 40 | """ 41 | Another benchmark method using custom metrics to demonstrate setting 42 | arrays for a metric, and to show that there's no crosstalk of metrics 43 | between benchmarks. 44 | """ 45 | # array of samples for custom metric 'my_other_metric' is set to 46 | # [1.2ms, 0.9ms, 1.1ms] 47 | self.set_metric_sample_array( 48 | name="my_other_metric", values=[1.2, 0.9, 1.1], unit="ms" 49 | ) 50 | await asyncio.sleep(0.01) 51 | 52 | 53 | class TestBenchmarksNoCustomMetric(AsyncTestCase): 54 | """ 55 | Example Benchmark class without custom metrics. 56 | * If you are not planning to use custom metrics you can derive from 57 | `AsyncTestCase`. 58 | * Benchmark methods have to start with the 'benchmark' prefix. 59 | * The runtime of the benchmark methods and their skip state 60 | belong to the default metrics which are always reported. 61 | """ 62 | 63 | def setUp(self): 64 | pass 65 | 66 | async def benchmark_sleepy_no_custom(self): 67 | await asyncio.sleep(0.1) 68 | -------------------------------------------------------------------------------- /readme-assets/additional-docs/developer_bundle_extensions.md: -------------------------------------------------------------------------------- 1 | # Developer Bundle Extensions 2 | 3 | ## Overview 4 | 5 | The Developer Bundle Extension (`omni.kit.developer.bundle`) provides a set of developer focused tools designed to enhance the development and debugging process within Omniverse Kit applications. Each of the extensions within the bundle aims streamline a specific aspects of Omniverse application and extension development. 6 | 7 | --- 8 | 9 | ## Enabling the Developer Bundle 10 | Application templates within the Kit App Template repository have `omni.kit.developer.bundle` configured within the `.kit` file by default. For applications that do not, the Developer Bundle can be added temporarily at launch time using the `--dev-bundle` or `-d` flag. 11 | 12 | **Linux** 13 | ```bash 14 | ./repo.sh launch --dev-bundle 15 | ``` 16 | 17 | **Windows** 18 | ```powershell 19 | .\repo.bat launch --dev-bundle 20 | ``` 21 | 22 | The `launch` tool will prompt for a selection of a `.kit` file to launch. Select the desired UI based application. The developer bundle is not currently suitable for headless services. 23 | 24 | --- 25 | 26 | ## Developer Bundle Extensions 27 | 28 | Developer Utilities are designed to assist developers in various aspects of application development, from debugging to extension management. These utilities offer insight into the internal workings of an application and its extensions. 29 | 30 | - **[Developer > Extensions] omni.kit.window.extensions**: The most popular utility, this tool manages available extensions. It provides quick access to the extension registry and local extensions, simplifying the process of adding dependencies for developer extensions and applications. 31 | 32 | - **[Developer > Commands] omni.kit.window.commands**: Captures the command history within a running application. It is particularly useful for developers who interact with the UI, allowing them to capture the commands used to execute specific functionalities. 33 | 34 | - **[Developer > Script Editor] omni.kit.window.script_editor**: A simplified script editor for running short code snippets directly within the application. It's a helpful tool for testing small pieces of code before integrating them into a project. Additionally, it offers useful sample scripts that can be executed live. 35 | 36 | - **[Developer > VS Code Link] omni.kit.debug.vscode**: VSCode python debugger support window. This utility allows developers to step through their python code in VSCode while running the application. 37 | 38 | - **[Developer > Debug Settings] omni.kit.debug.settings**: This utility provides a detailed view of the configurable settings for extensions within an application, making it easier to tweak and optimize extension behavior. 39 | 40 | --- 41 | 42 | **:warning: The Developer Bundle extensions require a UI based application with a menu bar to run properly. They will not work as expected for headless services or in applications that do not display a menu bar** -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/python/tests/test_pybind_example.py: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | ## 3 | ## NVIDIA CORPORATION and its licensors retain all intellectual property 4 | ## and proprietary rights in and to this software, related documentation 5 | ## and any modifications thereto. Any use, reproduction, disclosure or 6 | ## distribution of this software and related documentation without an express 7 | ## license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | ## 9 | import omni.kit.test 10 | 11 | import {{ python_module }} 12 | 13 | 14 | class TestPybindExample(omni.kit.test.AsyncTestCase): 15 | async def setUp(self): 16 | # Cache the pybind interface. 17 | self.bound_interface = {{ python_module }}.get_bound_interface() 18 | 19 | # Create and register a bound object. 20 | self.bound_object = {{ python_module }}.{{ object_name }}("test_bound_object") 21 | self.bound_object.property_int = 9 22 | self.bound_object.property_bool = True 23 | self.bound_object.property_string = "Ninety-Nine" 24 | self.bound_interface.register_bound_object(self.bound_object) 25 | 26 | async def tearDown(self): 27 | # Deregister and clear the bound object. 28 | self.bound_interface.deregister_bound_object(self.bound_object) 29 | self.bound_object = None 30 | 31 | # Clear the pybind interface. 32 | self.bound_interface = None 33 | 34 | async def test_find_bound_object(self): 35 | found_object = self.bound_interface.find_bound_object("test_bound_object") 36 | self.assertIsNotNone(found_object) 37 | 38 | async def test_find_unregistered_bound_object(self): 39 | found_object = self.bound_interface.find_bound_object("unregistered_object") 40 | self.assertIsNone(found_object) 41 | 42 | async def test_access_bound_object_properties(self): 43 | self.assertEqual(self.bound_object.id, "test_bound_object") 44 | self.assertEqual(self.bound_object.property_int, 9) 45 | self.assertEqual(self.bound_object.property_bool, True) 46 | self.assertEqual(self.bound_object.property_string, "Ninety-Nine") 47 | 48 | async def test_call_bound_object_functions(self): 49 | # Test calling a bound function that accepts an argument. 50 | self.bound_object.multiply_int_property(9) 51 | self.assertEqual(self.bound_object.property_int, 81) 52 | 53 | # Test calling a bound function that returns a value. 54 | result = self.bound_object.toggle_bool_property() 55 | self.assertEqual(result, False) 56 | self.assertEqual(self.bound_object.property_bool, False) 57 | 58 | # Test calling a bound function that accepts an argument and returns a value. 59 | result = self.bound_object.append_string_property(" Red Balloons") 60 | self.assertEqual(result, "Ninety-Nine Red Balloons") 61 | self.assertEqual(self.bound_object.property_string, "Ninety-Nine Red Balloons") 62 | -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/template/plugins/{{extension_name}}/CppExtension.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. 3 | * All rights reserved. 4 | * SPDX-License-Identifier: LicenseRef-NvidiaProprietary 5 | * 6 | * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual 7 | * property and proprietary rights in and to this material, related 8 | * documentation and any modifications thereto. Any use, reproduction, 9 | * disclosure or distribution of this material and related documentation 10 | * without an express license agreement from NVIDIA CORPORATION or 11 | * its affiliates is strictly prohibited. 12 | */ 13 | 14 | #define CARB_EXPORTS 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | 28 | #define EXTENSION_NAME "{{ extension_name }}.plugin" 29 | 30 | using namespace carb; 31 | 32 | // Plugin Implementation Descriptor 33 | const struct carb::PluginImplDesc kPluginImpl = { 34 | EXTENSION_NAME, // Name of the plugin (e.g. "carb.dictionary.plugin"). Must be globally unique. 35 | "Example of a native plugin extension.", // Helpful text describing the plugin. Used for debugging/tools. 36 | "NVIDIA", // Author 37 | carb::PluginHotReload::eDisabled, 38 | "dev" // Build version of the plugin. 39 | }; 40 | 41 | // List dependencies for this plugin 42 | CARB_PLUGIN_IMPL_DEPS(omni::kit::IApp, carb::logging::ILogging) 43 | 44 | 45 | class NativeExtensionExample : public omni::ext::IExt 46 | { 47 | public: 48 | void onStartup(const char* extId) override 49 | { 50 | printf(EXTENSION_NAME ": in onStartup\n"); 51 | // Get event dispatch interface using Carbonite Framework 52 | auto ed = carb::getCachedInterface(); 53 | m_subscription = ed->observeEvent( 54 | carb::RStringKey("cpp.example.update"), 55 | 0, 56 | omni::kit::kGlobalEventUpdate, 57 | [this](const carb::eventdispatcher::Event& e) { 58 | if (m_counter % 100 == 0) 59 | { 60 | printf(EXTENSION_NAME ": %d updates passed.\n", m_counter); 61 | CARB_LOG_INFO(EXTENSION_NAME ": %d updates passed.\n", m_counter); 62 | } 63 | m_counter++; 64 | }); 65 | } 66 | 67 | void onShutdown() override 68 | { 69 | // Unsubscribes from the event stream 70 | m_subscription.reset(); 71 | } 72 | 73 | private: 74 | int m_counter = 0; 75 | carb::eventdispatcher::ObserverGuard m_subscription; 76 | }; 77 | 78 | 79 | // Generate boilerplate code 80 | CARB_PLUGIN_IMPL(kPluginImpl, NativeExtensionExample) 81 | 82 | // There must be a fillInterface(InterfaceType&) function for each interface type that is exported by this plugin. 83 | void fillInterface(NativeExtensionExample& iface) 84 | { 85 | } 86 | -------------------------------------------------------------------------------- /tools/packman/packman.cmd: -------------------------------------------------------------------------------- 1 | :: RUN_PM_MODULE must always be at the same spot for packman update to work (batch reloads file during update!) 2 | :: [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] 3 | :: Reset errorlevel status (don't inherit from caller) 4 | @call :ECHO_AND_RESET_ERROR 5 | 6 | :: You can remove this section if you do your own manual configuration of the dev machines 7 | call :CONFIGURE 8 | if %errorlevel% neq 0 ( exit /b %errorlevel% ) 9 | 10 | :: Everything below is mandatory 11 | if not defined PM_PYTHON goto :PYTHON_ENV_ERROR 12 | if not defined PM_MODULE goto :MODULE_ENV_ERROR 13 | 14 | set PM_VAR_PATH_ARG= 15 | 16 | if "%1"=="pull" goto :SET_VAR_PATH 17 | if "%1"=="install" goto :SET_VAR_PATH 18 | 19 | :RUN_PM_MODULE 20 | "%PM_PYTHON%" -S -s -u -E "%PM_MODULE%" %* %PM_VAR_PATH_ARG% 21 | if %errorlevel% neq 0 ( exit /b %errorlevel% ) 22 | 23 | :: Marshall environment variables into the current environment if they have been generated and remove temporary file 24 | if exist "%PM_VAR_PATH%" ( 25 | for /F "usebackq tokens=*" %%A in ("%PM_VAR_PATH%") do set "%%A" 26 | ) 27 | if %errorlevel% neq 0 ( goto :VAR_ERROR ) 28 | 29 | if exist "%PM_VAR_PATH%" ( 30 | del /F "%PM_VAR_PATH%" 31 | ) 32 | if %errorlevel% neq 0 ( goto :VAR_ERROR ) 33 | 34 | set PM_VAR_PATH= 35 | goto :eof 36 | 37 | :: Subroutines below 38 | :PYTHON_ENV_ERROR 39 | @echo User environment variable PM_PYTHON is not set! Please configure machine for packman or call configure.bat. 40 | exit /b 1 41 | 42 | :MODULE_ENV_ERROR 43 | @echo User environment variable PM_MODULE is not set! Please configure machine for packman or call configure.bat. 44 | exit /b 1 45 | 46 | :VAR_ERROR 47 | @echo Error while processing and setting environment variables! 48 | exit /b 1 49 | 50 | :: pad [xxxx] 51 | :ECHO_AND_RESET_ERROR 52 | @echo off 53 | if /I "%PM_VERBOSITY%"=="debug" ( 54 | @echo on 55 | ) 56 | exit /b 0 57 | 58 | :SET_VAR_PATH 59 | :: Generate temporary path for variable file 60 | for /f "delims=" %%a in ('%PM_PYTHON% -S -s -u -E -c "import tempfile;file = tempfile.NamedTemporaryFile(mode='w+t', delete=False);print(file.name)"') do (set PM_VAR_PATH=%%a) 61 | set PM_VAR_PATH_ARG=--var-path="%PM_VAR_PATH%" 62 | goto :RUN_PM_MODULE 63 | 64 | :CONFIGURE 65 | :: Must capture and set code page to work around issue #279, powershell invocation mutates console font 66 | :: This issue only happens in Windows CMD shell when using 65001 code page. Some Git Bash implementations 67 | :: don't support chcp so this workaround is a bit convoluted. 68 | :: Test for chcp: 69 | chcp > nul 2>&1 70 | if %errorlevel% equ 0 ( 71 | for /f "tokens=2 delims=:" %%a in ('chcp') do (set PM_OLD_CODE_PAGE=%%a) 72 | ) else ( 73 | call :ECHO_AND_RESET_ERROR 74 | ) 75 | :: trim leading space (this is safe even when PM_OLD_CODE_PAGE has not been set) 76 | set PM_OLD_CODE_PAGE=%PM_OLD_CODE_PAGE:~1% 77 | if "%PM_OLD_CODE_PAGE%" equ "65001" ( 78 | chcp 437 > nul 79 | set PM_RESTORE_CODE_PAGE=1 80 | ) 81 | call "%~dp0\bootstrap\configure.bat" 82 | set PM_CONFIG_ERRORLEVEL=%errorlevel% 83 | if defined PM_RESTORE_CODE_PAGE ( 84 | :: Restore code page 85 | chcp %PM_OLD_CODE_PAGE% > nul 86 | ) 87 | set PM_OLD_CODE_PAGE= 88 | set PM_RESTORE_CODE_PAGE= 89 | exit /b %PM_CONFIG_ERRORLEVEL% 90 | -------------------------------------------------------------------------------- /templates/extensions/basic_python/README.md: -------------------------------------------------------------------------------- 1 | # Basic Python Extension Template 2 | 3 |

4 | 5 |

6 | 7 | ## Overview 8 | 9 | The Basic Python Extension Template is a starting point for developers looking to build Python-based extensions within the NVIDIA Omniverse ecosystem. This template offers a best practices foundation and structure to easily integrate with the broader capabilities of the Omniverse Kit SDK. 10 | 11 | ### Use Cases 12 | 13 | This template is ideal for developers looking to build: 14 | 15 | - A reusable Python extension that can be easily integrated with Omniverse Kit SDK applications. 16 | 17 | 18 | ### Key Features 19 | 20 | - Structure well suited for the build, test and packaging tooling within this repository. 21 | - All required setup code for use with the Omniverse Kit SDK. 22 | 23 | 24 | ## Usage 25 | 26 | This section provides instructions for the setup and use of the Basic Python Extension Template. 27 | 28 | ### Getting Started 29 | 30 | To get started with the Basic Python Extension, ensure your development environment meets the prerequisites outlined in the [top-level README](../../../README.md#prerequisites-and-environment-setup). 31 | 32 | #### Cloning the Repository 33 | 34 | ```bash 35 | git clone https://github.com/NVIDIA-Omniverse/kit-app-template.git 36 | cd kit-app-template 37 | ``` 38 | 39 | #### Create New Extension 40 | **Linux:** 41 | ```bash 42 | ./repo.sh template new 43 | ``` 44 | 45 | **Windows:** 46 | ```powershell 47 | .\repo.bat template new 48 | ``` 49 | 50 | Follow the prompt instructions: 51 | - **? Select what you want to create with arrow keys ↑↓:** Extension 52 | - **? Select desired template with arrow keys ↑↓:**: Basic Python Extension 53 | - **? Enter name of extension [name-spaced, lowercase, alphanumeric]:**: [set extension name] 54 | - **? Enter extension_display_name:**: [set extension display name] 55 | - **? Enter version:** [set extension version] 56 | 57 | #### Build and Launch 58 | 59 | While Python extensions typically do not require a build step in isolation, this template is structured to properly interact with the Omniverse Kit SDK application build and packaging tooling. 60 | 61 | Launching the extension typically requires that they be a part of an Omniverse [Service](../../apps/kit_service/README.md) or [Editor](../../apps/kit_base_editor/README.md) application. 62 | 63 | **Adding an Extension to an Application** 64 | 65 | To add your extension to an application, declare it in the dependencies section of the application's `.kit` file: 66 | 67 | ```toml 68 | [dependencies] 69 | "my_company.my_extension" = {} 70 | ``` 71 | 72 | #### Build with New Extensions 73 | After a new extension has been added to the `.kit` file, the application should be rebuilt to ensure extensions are populated to the build directory. 74 | 75 | ### Customization 76 | 77 | Customization of a Python Extension might involve writing new Python modules, or integrating existing libraries. 78 | 79 | As is the case with Applications, extensions can also depend on and be depended on by other extensions. These can be custom developed extensions or those provided by the NVIDIA managed extension registry. A view of available registry extensions can be found within the Extension Manager accessible via the developer bundle (select `Developer` > `Utilities` > `Extensions`) 80 | 81 | ## Additional Learning 82 | - [Kit Manual Extension Docs](https://docs.omniverse.nvidia.com/kit/docs/kit-manual/latest/guide/extensions_basic.html) 83 | - [Kit SDK Companion Tutorial](https://docs.omniverse.nvidia.com/kit/docs/kit-app-template/latest/docs/intro.html) -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/plugins/{{extension_name}}.tests/ExamplePybindTests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | 10 | #include <{{ python_module_path }}/{{ interface_name }}.h> 11 | #include <{{ python_module_path }}/{{ object_name }}.h> 12 | 13 | #include 14 | 15 | #include 16 | 17 | CARB_BINDINGS("{{ extension_name }}.tests") 18 | 19 | namespace {{ extension_namespace }} 20 | { 21 | 22 | class ExampleCppObject : public {{ object_name }} 23 | { 24 | public: 25 | static carb::ObjectPtr<{{ object_interface_name }}> create(const char* id) 26 | { 27 | return carb::stealObject<{{ object_interface_name }}>(new ExampleCppObject(id)); 28 | } 29 | 30 | ExampleCppObject(const char* id) 31 | : {{ object_name }}(id) 32 | { 33 | } 34 | }; 35 | 36 | class ExamplePybindTestFixture 37 | { 38 | public: 39 | static constexpr const char* k_registeredObjectId = "example_bound_object"; 40 | 41 | ExamplePybindTestFixture() 42 | : m_exampleBoundInterface(carb::getCachedInterface<{{ extension_namespace }}::{{ interface_name }}>()) 43 | , m_{{ object_name }}(ExampleCppObject::create(k_registeredObjectId)) 44 | { 45 | m_exampleBoundInterface->register{{object_name}}(m_{{ object_name }}); 46 | } 47 | 48 | ~ExamplePybindTestFixture() 49 | { 50 | m_exampleBoundInterface->deregister{{object_name}}(m_{{ object_name }}); 51 | } 52 | 53 | protected: 54 | {{ interface_name }}* getExampleBoundInterface() 55 | { 56 | return m_exampleBoundInterface; 57 | } 58 | 59 | carb::ObjectPtr<{{ object_interface_name }}> get{{ object_name }}() 60 | { 61 | return m_{{ object_name }}; 62 | } 63 | 64 | private: 65 | {{ interface_name }}* m_exampleBoundInterface = nullptr; 66 | carb::ObjectPtr<{{ object_interface_name }}> m_{{ object_name }}; 67 | }; 68 | 69 | } 70 | 71 | TEST_SUITE("{{ extension_name }}.tests") 72 | { 73 | using namespace {{ extension_namespace }} 74 | ; 75 | 76 | TEST_CASE_FIXTURE(ExamplePybindTestFixture, "Get Example Bound Interface") 77 | { 78 | CHECK(getExampleBoundInterface() != nullptr); 79 | } 80 | 81 | TEST_CASE_FIXTURE(ExamplePybindTestFixture, "Get Example Bound Object") 82 | { 83 | CHECK(get{{ object_name }}().get() != nullptr); 84 | } 85 | 86 | TEST_CASE_FIXTURE(ExamplePybindTestFixture, "Find Example Bound Object") 87 | { 88 | SUBCASE("Registered") 89 | { 90 | carb::ObjectPtr<{{ object_interface_name }}> foundObject = getExampleBoundInterface()->find{{object_name}}(k_registeredObjectId); 91 | CHECK(foundObject.get() == get{{ object_name }}().get()); 92 | CHECK(foundObject.get() != nullptr); 93 | } 94 | 95 | SUBCASE("Unregistered") 96 | { 97 | carb::ObjectPtr<{{ object_interface_name }}> foundObject = getExampleBoundInterface()->find{{object_name}}("unregistered_object_id"); 98 | CHECK(foundObject.get() != get{{ object_name }}().get()); 99 | CHECK(foundObject.get() == nullptr); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /templates/extensions/python_ui/README.md: -------------------------------------------------------------------------------- 1 | # Python UI Extension Template 2 | 3 |

4 | 5 |

6 | 7 | ## Overview 8 | 9 | The Python UI Extension Template offers a simple starting point for developers looking to build Python-based extensions with performant User Interfaces. This template offers a best practices foundation and structure to easily integrate with the broader capabilities of the Omniverse Kit SDK. 10 | 11 | ### Use Cases 12 | 13 | This template is ideal for developers looking to build: 14 | 15 | - UI based extensions that can be easily integrated with Omniverse Kit SDK applications. 16 | 17 | 18 | ### Key Features 19 | 20 | - A simple starter UI demonstrating how to build using the Omni UI framework. 21 | - Structure well suited for the build, test and packaging tooling within this repository. 22 | - All required setup code for use with the Omniverse Kit SDK. 23 | 24 | 25 | ## Usage 26 | 27 | This section provides instructions for the setup and use of the Python UI Extension Template. 28 | 29 | ### Getting Started 30 | 31 | To get started with the Python UI Extension, ensure your development environment meets the prerequisites outlined in the [top-level README](../../../README.md#prerequisites-and-environment-setup). 32 | 33 | #### Cloning the Repository 34 | 35 | ```bash 36 | git clone https://github.com/NVIDIA-Omniverse/kit-app-template.git 37 | cd kit-app-template 38 | ``` 39 | 40 | #### Create New Extension 41 | **Linux:** 42 | ```bash 43 | ./repo.sh template new 44 | ``` 45 | 46 | **Windows:** 47 | ```powershell 48 | .\repo.bat template new 49 | ``` 50 | 51 | Follow the prompt instructions: 52 | - **? Select what you want to create with arrow keys ↑↓:** Extension 53 | - **? Select desired template with arrow keys ↑↓:**: Python UI Extension 54 | - **? Enter name of extension [name-spaced, lowercase, alphanumeric]:**: [set extension name] 55 | - **? Enter extension_display_name:**: [set extension display name] 56 | - **? Enter version:** [set extension version] 57 | 58 | #### Build and Launch 59 | 60 | While Python extensions typically do not require a build step in isolation, this template is structured to properly interact with the Omniverse Kit SDK application build and packaging tooling. 61 | 62 | Launching the extension typically requires that they be a part of an Omniverse [Service](../../apps/kit_service/README.md) or [Editor](../../apps/kit_base_editor/README.md) application. 63 | 64 | **Adding an Extension to an Application** 65 | 66 | To add your extension to an application, declare it in the dependencies section of the application's `.kit` file: 67 | 68 | ```toml 69 | [dependencies] 70 | "my_company.my_extension" = {} 71 | ``` 72 | 73 | #### Build with New Extensions 74 | After a new extension has been added to the `.kit` file, the application should be rebuilt to ensure extensions are populated to the build directory. 75 | 76 | ### Customization 77 | 78 | Customization of a Python Extension might involve writing new Python modules, or integrating existing libraries. 79 | 80 | As is the case with Applications, extensions can also depend on and be depended on by other extensions. These can be custom developed extensions or those provided by the NVIDIA managed extension registry. A view of available registry extensions can be found within the Extension Manager accessible via the developer bundle (select `Developer` > `Utilities` > `Extensions`) 81 | 82 | ## Additional Learning 83 | - [Kit Manual Extension Docs](https://docs.omniverse.nvidia.com/kit/docs/kit-manual/latest/guide/extensions_basic.html) 84 | - [Omni UI Documentation](https://docs.omniverse.nvidia.com/kit/docs/omni.ui) 85 | - [Kit SDK Companion Tutorial](https://docs.omniverse.nvidia.com/kit/docs/kit-app-template/latest/docs/intro.html) -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "New Template", 8 | "type": "shell", 9 | "command": "${workspaceRoot}${/}repo.sh", 10 | "windows": { 11 | "command": "${workspaceRoot}${/}repo.bat" 12 | }, 13 | "args": [ 14 | "template", 15 | "new" 16 | ], 17 | "group": "none", 18 | "presentation": { 19 | "reveal": "always", 20 | "focus": true 21 | } 22 | }, 23 | { 24 | "label": "Build", 25 | "type": "shell", 26 | "command": "${workspaceRoot}${/}repo.sh", 27 | "windows": { 28 | "command": "${workspaceRoot}${/}repo.bat" 29 | }, 30 | "args": [ 31 | "build" 32 | ], 33 | "group": { 34 | "kind": "build", 35 | "isDefault": true 36 | }, 37 | "presentation": { 38 | "reveal": "always", 39 | "focus": false 40 | }, 41 | "problemMatcher": [] 42 | }, 43 | { 44 | "label": "Launch", 45 | "type": "shell", 46 | "command": "${workspaceRoot}${/}repo.sh", 47 | "windows": { 48 | "command": "${workspaceRoot}${/}repo.bat" 49 | }, 50 | "args": [ 51 | "launch" 52 | ], 53 | "group": "none", 54 | "presentation": { 55 | "reveal": "always", 56 | "focus": true 57 | } 58 | }, 59 | { 60 | "label": "Launch (Developer Mode)", 61 | "type": "shell", 62 | "command": "${workspaceRoot}${/}repo.sh", 63 | "windows": { 64 | "command": "${workspaceRoot}${/}repo.bat" 65 | }, 66 | "args": [ 67 | "launch", 68 | "-d" 69 | ], 70 | "group": "none", 71 | "presentation": { 72 | "reveal": "always", 73 | "focus": true 74 | } 75 | }, 76 | { 77 | "label": "Run Unit Tests", 78 | "type": "shell", 79 | "command": "${workspaceRoot}${/}repo.sh", 80 | "windows": { 81 | "command": "${workspaceRoot}${/}repo.bat" 82 | }, 83 | "args": [ 84 | "test", 85 | ], 86 | "group": "none", 87 | "presentation": { 88 | "reveal": "always", 89 | "focus": false 90 | } 91 | }, 92 | { 93 | "label": "Package", 94 | "type": "shell", 95 | "command": "${workspaceRoot}${/}repo.sh", 96 | "windows": { 97 | "command": "${workspaceRoot}${/}repo.bat" 98 | }, 99 | "args": [ 100 | "package" 101 | ], 102 | "group": "none", 103 | "presentation": { 104 | "reveal": "always", 105 | "focus": false 106 | } 107 | }, 108 | { 109 | "label": "Build All Templates", 110 | "type": "shell", 111 | "command": "${workspaceRoot}${/}tools${/}packman${/}python.sh", 112 | "windows": { 113 | "command": "${workspaceRoot}${/}tools${/}packman${/}python.bat" 114 | }, 115 | "args": [ 116 | "${workspaceRoot}${/}.vscode${/}template_builder.py", 117 | ], 118 | "group": "none", 119 | "presentation": { 120 | "reveal": "always", 121 | "focus": false 122 | } 123 | } 124 | ] 125 | } -------------------------------------------------------------------------------- /templates/extensions/basic_cpp/README.md: -------------------------------------------------------------------------------- 1 | # Basic C++ Extension Template 2 | 3 |

4 | 5 |

6 | 7 | ## Overview 8 | 9 | The Basic C++ Extension Template is a starting point for developers looking to build C++ based extensions within the NVIDIA Omniverse ecosystem. This template offers a best practices foundation and structure to easily integrate with the broader capabilities of the Omniverse Kit SDK. 10 | 11 | **Note for Windows C++ Developers** : This template requires that Visual Studio is installed on the host. Additionally, `"platform:windows-x86_64".enabled` and `link_host_toolchain` within the `repo.toml` file be set to `true`. For additional C++ configuration information [see here](../../../readme-assets/additional-docs/windows_developer_configuration.md). 12 | 13 | ### Use Cases 14 | 15 | This template is ideal for developers looking to build: 16 | 17 | - A reusable C++ extension that can be easily integrated with Omniverse Kit SDK applications. 18 | - Performance sensitive extensions that require the performance benefits of C++. 19 | - Extensions that require direct access to the Omniverse Kit or Carbonite SDK C++ API. 20 | - Integrating with existing C++ libraries or codebases. 21 | 22 | 23 | ### Key Features 24 | 25 | - Structure well suited for the build, test and packaging tooling within this repository. 26 | - All required setup code for use with the Omniverse Kit SDK. 27 | 28 | 29 | ## Usage 30 | 31 | This section provides instructions for the setup and use of the Basic C++ Extension Template. 32 | 33 | ### Getting Started 34 | 35 | To get started with the Basic C++ Extension, ensure your development environment meets the prerequisites outlined in the [top-level README](../../../README.md#prerequisites-and-environment-setup). 36 | 37 | #### Cloning the Repository 38 | 39 | ```bash 40 | git clone https://github.com/NVIDIA-Omniverse/kit-app-template.git 41 | cd kit-app-template 42 | ``` 43 | 44 | #### Create New Extension 45 | **Linux:** 46 | ```bash 47 | ./repo.sh template new 48 | ``` 49 | 50 | **Windows:** 51 | ```powershell 52 | .\repo.bat template new 53 | ``` 54 | 55 | Follow the prompt instructions: 56 | - **? Select what you want to create with arrow keys ↑↓:** Extension 57 | - **? Select desired template with arrow keys ↑↓:** Basic C++ Extension 58 | - **? Enter name of extension [name-spaced, lowercase, alphanumeric]:** [set extension name] 59 | - **? Enter extension_display_name:** [set extension display name] 60 | - **? Enter version:** [set extension version] 61 | 62 | #### Build and Launch 63 | 64 | While C++ extensions do require compilation this is typically not done in isolation, this template is structured to properly interact with the Omniverse Kit SDK application build and packaging tooling. 65 | 66 | Launching the extension typically requires that they be a part of an Omniverse [Service](../../apps/kit_service/README.md) or [Editor](../../apps/kit_base_editor/README.md) application. 67 | 68 | **Adding an Extension to an Application** 69 | 70 | To add your extension to an application, declare it in the dependencies section of the application's `.kit` file: 71 | 72 | ```toml 73 | [dependencies] 74 | "my_company.my_extension" = {} 75 | ``` 76 | 77 | #### Build with New Extensions 78 | After a new extension has been added to the `.kit` file, the application should be rebuilt to ensure extensions are populated to the build directory. 79 | 80 | 81 | ### Customization 82 | 83 | Customization of a C++ Extension might involve writing new C++ classes or functions, or integrating existing libraries. 84 | 85 | As is the case with Applications, extensions can also depend on and be depended on by other extensions. These can be custom developed extensions or those provided by the NVIDIA managed extension registry. **It should be noted that a limited number of registry extensions expose a C++ API**. A view of available registry extensions can be found within the Extension Manager accessible via the developer bundle (select `Developer` > `Utilities` > `Extensions`). 86 | 87 | ## Additional Learning 88 | - [Kit Manual Extension Docs](https://docs.omniverse.nvidia.com/kit/docs/kit-manual) 89 | - [C++ Extension Examples](https://github.com/NVIDIA-Omniverse/kit-extension-template-cpp) 90 | - [Kit SDK Companion Tutorial](https://docs.omniverse.nvidia.com/kit/docs/kit-app-template/latest/docs/intro.html) -------------------------------------------------------------------------------- /readme-assets/additional-docs/kit_app_streaming_config.md: -------------------------------------------------------------------------------- 1 | # Kit Application Streaming 2 | 3 | ## Overview 4 | 5 | Kit SDK templates and tooling enable the creation streaming-ready Omniverse Kit applications and aid in the packaging/containerization in preparation for deployment. This document outlines how to set up, configure, and package Kit applications for a streaming deployment. 6 | 7 | :warning: **Important :** For **Omniverse Kit App Streaming** or **Omniverse Cloud (OVC)**, you must containerize your application in a Linux environment to enable streaming. 8 | 9 | ## Create and Configure an Application 10 | 11 | Choose a template from the options below, then follow the instructions in the template README.md to create your application using the `template new` command: 12 | 13 | - **[Kit Base Editor](../../templates/apps/kit_base_editor/)**: A minimal application for loading, manipulating, and rendering OpenUSD content through a graphical interface. 14 | - **[USD Composer](../../templates/apps/usd_composer)**: A template for authoring complex OpenUSD scenes (e.g., configurators). 15 | - **[USD Explorer](../../templates/apps/usd_explorer)**: A template for exploring and collaborating on large OpenUSD scenes. 16 | - **[USD Viewer](../../templates/apps/usd_viewer)**: A streamlined, viewport-only application well-suited for remote streaming to web pages. 17 | 18 | :warning: **Important :** During the templating process, you will be prompted: 19 | 20 | ```bash 21 | Do you want to add application layers? 22 | ``` 23 | 24 | Answer `yes` to enable streaming for your application. You can then pick from the following streaming layers: 25 | 26 | ```bash 27 | ? Do you want to add application layers? Yes 28 | ? Browse layers with arrow keys ↑↓: [SPACE to toggle selection, ENTER to confirm selection(s)] 29 | ❯ [ ] [omni_default_streaming]: Omniverse Kit App Streaming (Default) 30 | [ ] [ovc_streaming]: Omniverse Cloud Streaming 31 | [ ] [omni_gdn_streaming]: GDN Streaming 32 | [ ] [ovc_streaming_legacy]: Omniverse Cloud Streaming (Legacy) 33 | ``` 34 | 35 | - **Omniverse Kit App Streaming (Default):** Ideal for self-managed streaming deployments or local streaming during development. 36 | - **Omniverse Cloud Streaming:** Suited for applications streamed through Omniverse Cloud, enabling Omniverse Connect and Omniverse Create (new or migrating customers should use this layer). 37 | - **GDN Streaming:** Streams applications through NVIDIA GDN; especially useful for configurator workflows. 38 | - **Omniverse Cloud Streaming (Legacy):** For existing customers on the legacy Omniverse Cloud platform. 39 | 40 | After creating your application, you’ll find two `.kit` files in the `/source/apps/` directory: 41 | - `{app_name}.kit`: The main application configuration file. 42 | - `{app_name}_{streaming_config}.kit`: The streaming configuration file. 43 | 44 | ## Build Your Application 45 | After you have created and customized your application, build it using the following command: 46 | 47 | ```bash 48 | ./repo.sh build 49 | ``` 50 | 51 | ## Packaging Your Application 52 | 53 | - **Omniverse Kit App Streaming** & **Omniverse Cloud** 54 | From a **Linux** development environment, run the following command to containerize your application for streaming: 55 | 56 | ```bash 57 | ./repo.sh package --container --name {container name} 58 | ``` 59 | 60 | :warning: **Note** 61 | When prompted to select a `.kit` file, choose the `{app_name}_{streaming_config}.kit` file. 62 | 63 | - **GDN Streaming** 64 | Refer to the [End-to-End Configurator Example Guide](https://docs.omniverse.nvidia.com/auto-config/latest/overview.html) for instructions on packaging and deploying to NVIDIA GDN. 65 | 66 | ## Testing Locally 67 | 68 | If you added the **Omniverse Kit App Streaming** layer, you can test your application locally. Follow the “Local Streaming” instructions in the template’s README: 69 | 70 | - [Kit Base Editor Local Streaming](../../templates/apps/kit_base_editor/README.md#local-streaming) 71 | - [USD Composer Local Streaming](../../templates/apps/usd_composer/README.md#local-streaming) 72 | - [USD Explorer Local Streaming](../../templates/apps/usd_explorer/README.md#local-streaming) 73 | - [USD Viewer Local Streaming](../../templates/apps/usd_viewer/README.md#local-streaming) 74 | 75 | ## Additional Resources 76 | 77 | - [Kit SDK Companion Tutorial](https://docs.omniverse.nvidia.com/kit/docs/kit-app-template/latest/docs/intro.html) -------------------------------------------------------------------------------- /.vscode/template_builder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tool to pair down a K-A-T binary artifact to only the extensions 3 | that need license and malware scanning. 4 | """ 5 | 6 | import argparse 7 | from pathlib import Path 8 | import platform 9 | import subprocess 10 | import sys 11 | 12 | ALL_EXTS_KIT_PARTIAL_PATH = Path("templates", "isaacsim.all.template.extensions.kit") 13 | SHELL_EXT = "sh" if platform.system() == "Linux" else "bat" 14 | 15 | 16 | def _template_new_all(repo_path: Path) -> None: 17 | """Creates all K-A-T templates""" 18 | 19 | print("\n----------------------------------------------------------------------------------------") 20 | print("*** Creating all templates...") 21 | print("----------------------------------------------------------------------------------------\n") 22 | 23 | company = "my_company" 24 | version = "0.1.0" 25 | commands = ( 26 | f"--input=Application>;[isaacsim.exp.template.base]: Minimal Sim Application;DEFAULT;DEFAULT;{version};DEFAULT;DEFAULT;{version};DEFAULT;DEFAULT;{version};{version};{version};DEFAULT;DEFAULT;{version};", 27 | f"--input=Application>;[isaacsim.exp.template.full]: Full Sim Application;DEFAULT;DEFAULT;{version};DEFAULT;DEFAULT;{version};DEFAULT;DEFAULT;{version};{version};{version};DEFAULT;DEFAULT;{version};", 28 | f"--input=Extension>;[basic_python_extension]: Basic Python Extension;{company}.basic_python_extension;DEFAULT;DEFAULT;", 29 | f"--input=Extension>;[basic_cpp_extension]: Basic C++ Extension;{company}.basic_cpp_extension;DEFAULT;DEFAULT;", 30 | f"--input=Extension>;[basic_python_ui_extension]: Python UI Extension;{company}.basic_python_ui_extension;DEFAULT;DEFAULT;", 31 | ) 32 | 33 | for cmd in commands: 34 | repo_args = [ 35 | f"{repo_path}", # shell ext has already been appended. 36 | "template", 37 | "new", 38 | f"{cmd}", 39 | ] 40 | subprocess.run(repo_args, check=False) 41 | 42 | 43 | def create_and_build_templates( 44 | arg_parser: argparse.ArgumentParser, 45 | source_dir: Path) -> None: 46 | """ 47 | Creates all K-A-T templates and builds them. 48 | """ 49 | 50 | repo_path = source_dir.joinpath(f"repo.{SHELL_EXT}") 51 | if not repo_path.exists(): 52 | arg_parser.error( 53 | "Could not find the repo shell script in the provided Kit-App-Template repository. Exiting." 54 | ) 55 | sys.exit(1) 56 | 57 | _template_new_all(repo_path) 58 | 59 | print("\n----------------------------------------------------------------------------------------") 60 | print("*** Building all applications and extensions...") 61 | print("----------------------------------------------------------------------------------------\n") 62 | subprocess.run([f"{repo_path}", "build"], check=False) 63 | 64 | 65 | def is_valid_kat_repo(arg_parser: argparse.ArgumentParser, arg: Path) -> bool: 66 | """ 67 | Determines if the provided Path points to a valid Kit-App-Template repo. 68 | """ 69 | 70 | if not arg.exists(): 71 | arg_parser.error(f"The path {arg} does not exist. Exiting.") 72 | return False 73 | if not arg.joinpath(ALL_EXTS_KIT_PARTIAL_PATH).exists(): 74 | arg_parser.error( 75 | f"The path {arg} does not appear to be a Kit-App-Template repository. Exiting." 76 | ) 77 | return False 78 | return True 79 | 80 | 81 | if __name__ == "__main__": 82 | parser = argparse.ArgumentParser( 83 | description="This will create all templates, build them, and optionally run all unit tests for them." 84 | ) 85 | 86 | parser.add_argument( 87 | "--source_dir", 88 | "-k", 89 | type=Path, 90 | default=Path.cwd(), 91 | help="An absolute path to your locally cloned Kit-App-Template repository.", 92 | dest="source_dir", 93 | nargs=1 94 | ) 95 | 96 | args = parser.parse_args() 97 | 98 | if not is_valid_kat_repo(parser, args.source_dir): 99 | print("This tool can only process Kit-App-Template repositories. Exiting...") 100 | sys.exit(1) 101 | 102 | create_and_build_templates(parser, args.source_dir) 103 | 104 | print("\n----------------------------------------------------------------------------------------") 105 | print("*** Done! ***") 106 | print("----------------------------------------------------------------------------------------") 107 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/docs/Overview.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | An example C++ extension that can be used as a reference/template for creating new extensions. 4 | 5 | Demonstrates how to reflect C++ code using pybind11 so that it can be called from Python code. 6 | 7 | The {{ interface_name }} located in `include/{{ python_module_path }}/{{ interface_name }}.h` is: 8 | - Implemented in `plugins/{{ extension_name }}/ExamplePybindExtension.cpp`. 9 | - Reflected in `bindings/python/{{ extension_name }}/ExamplePybindBindings.cpp`. 10 | - Accessed from Python in `python/tests/test_pybind_example.py` via `python/impl/example_pybind_extension.py`. 11 | 12 | 13 | # C++ Usage Examples 14 | 15 | 16 | ## Defining Pybind Module 17 | 18 | 19 | ``` 20 | PYBIND11_MODULE({{ library_name }}, m) 21 | { 22 | using namespace {{ extension_namespace }} 23 | ; 24 | 25 | m.doc() = "pybind11 {{ extension_name }} bindings"; 26 | 27 | carb::defineInterfaceClass<{{ interface_name }}>( 28 | m, "{{ interface_name }}", "acquire_bound_interface", "release_bound_interface") 29 | .def("register_bound_object", &{{ interface_name }}::register{{object_name}}, 30 | R"( 31 | Register a bound object. 32 | 33 | Args: 34 | object: The bound object to register. 35 | )", 36 | py::arg("object")) 37 | .def("deregister_bound_object", &{{ interface_name }}::deregister{{object_name}}, 38 | R"( 39 | Deregister a bound object. 40 | 41 | Args: 42 | object: The bound object to deregister. 43 | )", 44 | py::arg("object")) 45 | .def("find_bound_object", &{{ interface_name }}::find{{object_name}}, py::return_value_policy::reference, 46 | R"( 47 | Find a bound object. 48 | 49 | Args: 50 | id: Id of the bound object. 51 | 52 | Return: 53 | The bound object if it exists, an empty object otherwise. 54 | )", 55 | py::arg("id")) 56 | /**/; 57 | 58 | py::class_<{{ object_interface_name }}, carb::ObjectPtr<{{ object_interface_name }}>>(m, "{{ object_interface_name }}") 59 | .def_property_readonly("id", &{{ object_interface_name }}::getId, py::return_value_policy::reference, 60 | R"( 61 | Get the id of this bound object. 62 | 63 | Return: 64 | The id of this bound object. 65 | )") 66 | /**/; 67 | 68 | py::class_>(m, "{{object_name}}") 69 | .def(py::init([](const char* id) { return Python{{object_name}}::create(id); }), 70 | R"( 71 | Create a bound object. 72 | 73 | Args: 74 | id: Id of the bound object. 75 | 76 | Return: 77 | The bound object that was created. 78 | )", 79 | py::arg("id")) 80 | .def_readwrite("property_int", &Python{{object_name}}::m_memberInt, 81 | R"( 82 | Int property bound directly. 83 | )") 84 | .def_readwrite("property_bool", &Python{{object_name}}::m_memberBool, 85 | R"( 86 | Bool property bound directly. 87 | )") 88 | .def_property("property_string", &Python{{object_name}}::getMemberString, &Python{{object_name}}::setMemberString, py::return_value_policy::reference, 89 | R"( 90 | String property bound using accessors. 91 | )") 92 | .def("multiply_int_property", &Python{{object_name}}::multiplyIntProperty, 93 | R"( 94 | Bound fuction that accepts an argument. 95 | 96 | Args: 97 | value_to_multiply: The value to multiply by. 98 | )", 99 | py::arg("value_to_multiply")) 100 | .def("toggle_bool_property", &Python{{object_name}}::toggleBoolProperty, 101 | R"( 102 | Bound fuction that returns a value. 103 | 104 | Return: 105 | The toggled bool value. 106 | )") 107 | .def("append_string_property", &Python{{object_name}}::appendStringProperty, py::return_value_policy::reference, 108 | R"( 109 | Bound fuction that accepts an argument and returns a value. 110 | 111 | Args: 112 | value_to_append: The value to append. 113 | 114 | Return: 115 | The new string value. 116 | )", 117 | py::arg("value_to_append")) 118 | /**/; 119 | } 120 | ``` 121 | -------------------------------------------------------------------------------- /templates/templates.toml: -------------------------------------------------------------------------------- 1 | # -- Application templates -- 2 | [templates."isaacsim.exp.template.base"] 3 | class = "ApplicationTemplate" 4 | name = "Minimal Sim Application" 5 | url = "." 6 | subpath = "apps/isaacsim/isaacsim.exp.template.base.kit" 7 | variables.application_name = "isaacsim.exp.template.base" 8 | variables.application_display_name = "Base Simulator Template" 9 | variables.version = "0.1.0" 10 | 11 | [[templates."isaacsim.exp.template.base".applications]] 12 | template = "isaacsim.exp.template.fabric" 13 | type = "fabric" 14 | 15 | [[templates."isaacsim.exp.template.base".applications]] 16 | template = "isaacsim.exp.template.streaming" 17 | type = "streaming" 18 | 19 | [[templates."isaacsim.exp.template.base".applications]] 20 | template = "isaacsim.exp.template.zero_delay" 21 | type = "zero_delay" 22 | 23 | [[templates."isaacsim.exp.template.base".applications]] 24 | template = "isaacsim.exp.template.ros2" 25 | type = "ros2" 26 | 27 | [[templates."isaacsim.exp.template.base".applications]] 28 | template = "isaacsim.exp.template.replicator" 29 | type = "replicator" 30 | 31 | [templates."isaacsim.exp.template.full"] 32 | class = "ApplicationTemplate" 33 | name = "Full Sim Application" 34 | url = "." 35 | subpath = "apps/isaacsim/isaacsim.exp.template.full.kit" 36 | variables.application_name = "isaacsim.exp.template.full" 37 | variables.application_display_name = "Full Simulator Template" 38 | variables.version = "0.1.0" 39 | 40 | [[templates."isaacsim.exp.template.full".applications]] 41 | template = "isaacsim.exp.template.fabric" 42 | type = "fabric" 43 | 44 | [[templates."isaacsim.exp.template.full".applications]] 45 | template = "isaacsim.exp.template.streaming" 46 | type = "streaming" 47 | 48 | [[templates."isaacsim.exp.template.full".applications]] 49 | template = "isaacsim.exp.template.zero_delay" 50 | type = "zero_delay" 51 | 52 | # -- Application Layer templates -- 53 | [templates."isaacsim.exp.template.fabric"] 54 | class = "ApplicationLayerTemplate" 55 | name = "Fabric Enabled Config" 56 | url = "." 57 | subpath = "apps/isaacsim_configs/isaacsim.exp.template.fabric.kit" 58 | variables.version = "0.1.0" 59 | type = "fabric" 60 | 61 | [templates."isaacsim.exp.template.zero_delay"] 62 | class = "ApplicationLayerTemplate" 63 | name = "Zero Delay" 64 | url = "." 65 | subpath = "apps/isaacsim_configs/isaacsim.exp.template.zero_delay.kit" 66 | variables.version = "0.1.0" 67 | type = "zero_delay" 68 | 69 | [templates."isaacsim.exp.template.ros2"] 70 | class = "ApplicationLayerTemplate" 71 | name = "ROS2" 72 | url = "." 73 | subpath = "apps/isaacsim_configs/isaacsim.exp.template.ros2.kit" 74 | variables.version = "0.1.0" 75 | type = "ros2" 76 | 77 | [templates."isaacsim.exp.template.replicator"] 78 | class = "ApplicationLayerTemplate" 79 | name = "Replicator" 80 | url = "." 81 | subpath = "apps/isaacsim_configs/isaacsim.exp.template.replicator.kit" 82 | variables.version = "0.1.0" 83 | type = "replicator" 84 | 85 | [templates."isaacsim.exp.template.streaming"] 86 | class = "ApplicationLayerTemplate" 87 | name = "Streaming" 88 | url = "." 89 | subpath = "apps/isaacsim_configs/isaacsim.exp.template.streaming.kit" 90 | variables.version = "0.1.0" 91 | type = "streaming" 92 | 93 | [templates."omni_ovc_streaming"] 94 | class = "ApplicationLayerTemplate" 95 | name = "Omniverse Cloud Streaming (Legacy)" 96 | url = "." 97 | subpath = "apps/streaming_configs/ovc_stream_legacy.kit" 98 | type = "ovc_legacy" 99 | variables.version = "0.1.0" 100 | 101 | 102 | # -- Extension templates -- 103 | [templates."basic_python_extension"] 104 | class = "ExtensionTemplate" 105 | name = "Basic Python Extension" 106 | url = "." 107 | subpath = "extensions/basic_python/template" 108 | variables.extension_name = "my_company.my_python_extension" 109 | variables.extension_display_name = "My Python Extension" 110 | variables.version = "0.1.0" 111 | 112 | [templates."basic_python_ui_extension"] 113 | class = "ExtensionTemplate" 114 | name = "Python UI Extension" 115 | url = "." 116 | subpath = "extensions/python_ui/template" 117 | variables.extension_name = "my_company.my_python_ui_extension" 118 | variables.extension_display_name = "My Python UI Extension" 119 | variables.version = "0.1.0" 120 | 121 | [templates."basic_cpp_extension"] 122 | class = "ExtensionTemplate" 123 | name = "Basic C++ Extension" 124 | url = "." 125 | subpath = "extensions/basic_cpp/template" 126 | variables.extension_name = "my_company.my_cpp_extension" 127 | variables.extension_display_name = "My C++ Extension" 128 | variables.version = "0.1.0" 129 | 130 | [templates."basic_python_binding"] 131 | class = "BindingExtensionTemplate" 132 | name = "Basic C++ w/ Python Binding Extension" 133 | url = "." 134 | subpath = "extensions/basic_python_binding/template" 135 | variables.extension_name = "my_company.my_python_binding" 136 | variables.extension_display_name = "My Pybind11 Extension" 137 | variables.version = "0.1.0" 138 | -------------------------------------------------------------------------------- /readme-assets/additional-docs/windows_developer_configuration.md: -------------------------------------------------------------------------------- 1 | # Windows C++ Developer Configuration 2 | 3 | ## Introduction 4 | 5 | This document guides you through setting up this repository for C++ development on Windows using Microsoft Visual Studio and the Windows SDK. 6 | 7 | **For New Users:** If you are new to Windows C++ development, this guide provides a step-by-step installation of Visual Studio 2022 Community and the Windows SDK, ensuring you have all the components required for standard development tasks. 8 | 9 | **For Advanced Configurations:** If you already have Visual Studio and the Windows SDK installed but wish to specify exact versions, this guide will help you configure your environment using the `[repo_build.msbuild]` configuration within `repo.toml` at the project root. 10 | 11 | ## Configuration 12 | 13 | To enable the Windows C++ build process: 14 | 15 | - Set the `"platform:windows-x86_64".enabled` flag to `true` in your `repo.toml` file: 16 | 17 | ```toml 18 | [repo_build.build] 19 | "platform:windows-x86_64".enabled = true 20 | ``` 21 | 22 | - Set the `link_host_toolchain` flag to `true` in your `repo.toml` file: 23 | 24 | ```toml 25 | [repo_build.msbuild] 26 | link_host_toolchain = true 27 | ``` 28 | 29 | **Note:** If you already have Visual Studio and the Windows SDK installed, this might be the only change needed. The tooling will auto-detect installed components. 30 | 31 | ## Microsoft Visual Studio and Windows SDK Setup 32 | 33 | ### Basic Installation 34 | 35 | #### Installing Visual Studio 2022 Community 36 | 37 | 1. **Download Visual Studio Installer** 38 | 39 | ![VS Download](../vs_download.png) 40 | - Visit the [Visual Studio Downloads](https://visualstudio.microsoft.com/downloads/). 41 | - Click "Free download" under "Community". 42 | 43 | 2. **Run the Installer** 44 | - Open the downloaded installer. 45 | - Select "Community" edition and click "Install". 46 | 47 | 3. **Select Workloads** 48 | 49 | ![VS Workloads](../vs_workloads.png) 50 | - Check "Desktop development with C++". 51 | - This includes tools like the MSVC compiler and C++ libraries. 52 | 53 | 4. **Additional Components** 54 | ![VS Additional](../vs_additional.png) 55 | - If you need specific components, go to "Individual components". 56 | - Select additional tools as needed. 57 | 58 | 5. **Complete the Installation** 59 | - Proceed with the installation to download and set up all files. 60 | 61 | #### Installing Windows SDK (as needed) 62 | 63 | Usually, the Windows SDK is included with the "Desktop development with C++" workload. To verify or install it separately: 64 | 65 | 1. **Launch Visual Studio Installer** 66 | - Open the installer if it's not already running. 67 | 68 | 2. **Modify Installation** 69 | 70 | ![VS Modify](../vs_modify.png) 71 | - Click "Modify" on your Visual Studio installation. 72 | 73 | 3. **Verify Windows SDK** 74 | 75 | ![VS WinSDK Verify](../vs_winsdk_verify.png) 76 | - Ensure "Windows SDK" is selected under "Optional" sections or "Individual components". 77 | 78 | 4. **Apply Changes** 79 | - Click "Modify" to install or update the SDK. 80 | 81 | ### Configuring an Existing Installation 82 | 83 | #### Default Installation Paths 84 | 85 | If Visual Studio and the Windows SDK are installed in default locations, the build tooling will auto-detect them without additional configuration. 86 | 87 | - Default Windows SDK: `C:\Program Files (x86)\Windows Kits` 88 | - Default Visual Studio 2019: `C:\Program Files (x86)\Microsoft Visual Studio` 89 | - Default Visual Studio 2022: `C:\Program Files\Microsoft Visual Studio` 90 | 91 | #### Non-Default Installation Paths 92 | 93 | For installations at non-standard paths, specify them in `repo.toml`: 94 | 95 | ```toml 96 | [repo_build.msbuild] 97 | vs_path = "D:\\CustomPath\\Visual Studio\\2022\\Community" 98 | winsdk_path = "D:\\CustomPath\\Windows Kits\\10\\bin\\10.0.19041.0" 99 | ``` 100 | 101 | Adjust and save the paths as needed. 102 | 103 | **Note:** If the path entered is incorrect or invalid, the build system will fall back to auto-detection. 104 | 105 | #### Multiple Installations 106 | 107 | For multiple Visual Studio or Windows SDK installations, the latest version is used by default. If unspecified, default edition preference is "Enterprise", "Professional", "Community". To specify preferred versions, editions, or paths: 108 | 109 | ##### Visual Studio 110 | 111 | ```toml 112 | [repo_build.msbuild] 113 | vs_version = "vs2022" 114 | vs_edition = "Community" 115 | vs_path = "D:\\AnotherPath\\Visual Studio\\2022\\Enterprise\\" 116 | ``` 117 | 118 | ##### Windows SDK 119 | 120 | ```toml 121 | [repo_build.msbuild] 122 | winsdk_version = "10.0.19041.0" 123 | winsdk_path = "D:\\CustomSDKPath\\Windows Kits\\10\\bin\\10.0.19041.0" 124 | ``` 125 | 126 | With these configurations, you control which versions the build system uses, ensuring consistency in environments with multiple installations. 127 | 128 | ## Additional Resources 129 | - [Repo Build Documentation](https://docs.omniverse.nvidia.com/kit/docs/repo_build/1.0.0/) -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/README.md: -------------------------------------------------------------------------------- 1 | # C++ with Python Bindings Extension Template 2 | 3 |

4 | 5 |

6 | 7 | ## Overview 8 | 9 | The C++ with Python Bindings Extension Template is a starting point for developers who need the performance benefits of C++ while offering a Python-friendly interface through Pybind11. Designed for the NVIDIA Omniverse ecosystem, this template provides a best-practices structure to seamlessly integrate with the Omniverse Kit SDK and enable easy consumption of extension features from Python. 10 | 11 | **Note for Windows C++ Developers**: This template requires that Visual Studio be installed on the host. Additionally, `"platform:windows-x86_64".enabled` and `link_host_toolchain` within the `repo.toml` file must be set to `true`. For more details, see the [Windows Developer Configuration guide](../../../readme-assets/additional-docs/windows_developer_configuration.md). 12 | 13 | ### Use Cases 14 | 15 | This template is ideal for developers looking to build: 16 | 17 | - A reusable C++ extension that can be easily integrated with Omniverse Kit SDK applications. 18 | - Performance-sensitive extensions that leverage C++ while still exposing a Python interface. 19 | - Extensions that require direct access to the Omniverse Kit or Carbonite SDK C++ API, with the added ability for Python scripting. 20 | - Integrations with existing C++ libraries or codebases while offering Python-friendly APIs for broader adoption. 21 | 22 | ### Key Features 23 | 24 | - Structure well suited for the build, test, and packaging tooling within this repository. 25 | - All required setup code for bridging C++ logic with Python using Pybind11. 26 | - Best practices for organizing C++ source and Python binding code into a single extension. 27 | - Smooth integration with the Omniverse Kit SDK for application deployment. 28 | 29 | ------------------------------------------------------------------------------- 30 | 31 | ## Usage 32 | 33 | This section details how to set up and use the C++ with Python Bindings Extension Template. 34 | 35 | ### Getting Started 36 | 37 | Before you begin, ensure your development environment meets the prerequisites outlined in the [top-level README](../../../README.md#prerequisites-and-environment-setup). 38 | 39 | #### Cloning the Repository 40 | 41 | Use the following steps to clone the repository locally: 42 | 43 | ```bash 44 | git clone https://github.com/NVIDIA-Omniverse/kit-app-template.git 45 | cd kit-app-template 46 | ``` 47 | 48 | #### Create New Extension 49 | 50 | Use the provided script (either shell or PowerShell) to start a new extension from the template. 51 | 52 | **Linux:** 53 | ```bash 54 | ./repo.sh template new 55 | ``` 56 | 57 | **Windows:** 58 | ```powershell 59 | .\repo.bat template new 60 | ``` 61 | 62 | Follow the prompts in your terminal: 63 | 64 | - **? Select what you want to create with arrow keys ↑↓:** Extension 65 | - **? Select desired template with arrow keys ↑↓:** Basic C++ w/ Python Binding Extension 66 | - **? Enter name of extension [name-spaced, lowercase, alphanumeric]:** [set extension name] 67 | - **? Enter extension_display_name:** [set extension display name] 68 | - **? Enter version:** [set extension version] 69 | 70 | #### Build and Launch 71 | 72 | While C++ extensions require a build step, this template is structured so that the build, test, and packaging processes are conveniently handled through the Omniverse Kit SDK’s application tooling. Python developers can then import the resulting module for a seamless C++-backed Python experience. 73 | 74 | Launching an extension typically requires that it be part of an Omniverse [Service](../../apps/kit_service/README.md) or [Editor](../../apps/kit_base_editor/README.md) application. 75 | 76 | **Adding an Extension to an Application** 77 | 78 | To add your extension to an application, declare it in the dependencies section of the application's `.kit` file: 79 | 80 | ```toml 81 | [dependencies] 82 | "my_company.my_extension" = {} 83 | ``` 84 | 85 | #### Build with New Extensions 86 | 87 | After adding your new extension, re-run the build process for the application. This ensures your compiled C++ code and Python bindings are included in the final build artifacts. 88 | 89 | ### Customization 90 | 91 | Customization of this C++/Python Binding Extension may involve: 92 | 93 | - Extending or altering the C++ source files to incorporate new functionalities. 94 | - Adjusting the Pybind11 binding code to expose additional methods, classes, or data structures to Python. 95 | - Integrating other C++ or Python libraries as needed. 96 | 97 | As with any extension, dependencies can be declared on other custom or registry-based extensions. Whether you need more specialized C++ libraries or Python packages, you can add them to your extension as desired. Note that only a limited number of registry extensions expose a C++ API, so validate your dependencies accordingly. 98 | 99 | ------------------------------------------------------------------------------- 100 | 101 | ## Additional Learning 102 | 103 | - [Kit Manual Extension Docs](https://docs.omniverse.nvidia.com/kit/docs/kit-manual/latest/guide/extensions_basic.html) 104 | - [C++ Extension Examples](https://github.com/NVIDIA-Omniverse/kit-extension-template-cpp) 105 | - [Kit SDK Companion Tutorial](https://docs.omniverse.nvidia.com/kit/docs/kit-app-template/latest/docs/intro.html) 106 | - [Pybind11 Documentation](https://pybind11.readthedocs.io/) -------------------------------------------------------------------------------- /tools/packman/packmanconf.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021-2024 NVIDIA CORPORATION 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Use this file to bootstrap packman into your Python environment. Simply 16 | # add the path by doing sys.insert to where packmanconf.py is located and then execute: 17 | # 18 | # >>> import packmanconf 19 | # >>> packmanconf.init() 20 | # 21 | # It will use the configured remote(s) and the version of packman in the same folder, 22 | # giving you full access to the packman API via the following module 23 | # 24 | # >> import packmanapi 25 | # >> dir(packmanapi) 26 | 27 | import os 28 | import platform 29 | import sys 30 | 31 | 32 | MIN_PYTHON_VERSION = (3, 10, 0) 33 | MAX_PYTHON_VERSION = (3, 11, 2) 34 | 35 | 36 | def is_valid_python_version(version: tuple[int, int, int] = sys.version_info[:3]): 37 | return MIN_PYTHON_VERSION <= version <= MAX_PYTHON_VERSION 38 | 39 | 40 | def validate_python_version(version: tuple[int, int, int] = sys.version_info[:3]): 41 | if not is_valid_python_version(version): 42 | 43 | def ver_str(pyver): 44 | return ".".join(str(x) for x in pyver) 45 | 46 | raise RuntimeError( 47 | f"This version of packman requires Python {ver_str(MIN_PYTHON_VERSION)} " 48 | f"up to {ver_str(MAX_PYTHON_VERSION)}, but {ver_str(version)} was provided" 49 | ) 50 | 51 | 52 | def init(): 53 | """Call this function to initialize the packman configuration. 54 | 55 | Calls to the packman API will work after successfully calling this function. 56 | 57 | Note: 58 | This function only needs to be called once during the execution of your 59 | program. Calling it repeatedly is harmless but wasteful. 60 | Compatibility with your Python interpreter is checked and upon failure 61 | the function will report what is required. 62 | 63 | Example: 64 | >>> import packmanconf 65 | >>> packmanconf.init() 66 | >>> import packmanapi 67 | >>> packmanapi.set_verbosity_level(packmanapi.VERBOSITY_HIGH) 68 | """ 69 | validate_python_version() 70 | conf_dir = os.path.dirname(os.path.abspath(__file__)) 71 | os.environ["PM_INSTALL_PATH"] = conf_dir 72 | packages_root = get_packages_root(conf_dir) 73 | version = get_version(conf_dir) 74 | module_dir = get_module_dir(conf_dir, packages_root, version) 75 | sys.path.insert(1, module_dir) 76 | 77 | 78 | def get_packages_root(conf_dir: str) -> str: 79 | root = os.getenv("PM_PACKAGES_ROOT") 80 | if not root: 81 | platform_name = platform.system() 82 | if platform_name == "Windows": 83 | drive, _ = os.path.splitdrive(conf_dir) 84 | root = os.path.join(drive, "packman-repo") 85 | elif platform_name == "Darwin": 86 | # macOS 87 | root = os.path.join( 88 | os.path.expanduser("~"), "Library/Application Support/packman-cache" 89 | ) 90 | elif platform_name == "Linux": 91 | try: 92 | cache_root = os.environ["XDG_HOME_CACHE"] 93 | except KeyError: 94 | cache_root = os.path.join(os.path.expanduser("~"), ".cache") 95 | return os.path.join(cache_root, "packman") 96 | else: 97 | raise RuntimeError(f"Unsupported platform '{platform_name}'") 98 | # make sure the path exists: 99 | os.makedirs(root, exist_ok=True) 100 | return root 101 | 102 | 103 | def get_module_dir(conf_dir, packages_root: str, version: str) -> str: 104 | module_dir = os.path.join(packages_root, "packman-common", version) 105 | if not os.path.exists(module_dir): 106 | import tempfile 107 | 108 | tf = tempfile.NamedTemporaryFile(delete=False) 109 | target_name = tf.name 110 | tf.close() 111 | # Forced to change to https because some customers will simply not allow http, 112 | # even when it's used in a safe way (with download checksum verification). 113 | # See issue #367 for more background. 114 | url = f"https://bootstrap.packman.nvidia.com/packman-common@{version}.zip" 115 | print(f"Downloading '{url}' ...") 116 | import urllib.request 117 | 118 | urllib.request.urlretrieve(url, target_name) 119 | from importlib.machinery import SourceFileLoader 120 | 121 | # import module from path provided 122 | script_path = os.path.join(conf_dir, "bootstrap", "install_package.py") 123 | ip = SourceFileLoader("install_package", script_path).load_module() 124 | print("Unpacking ...") 125 | ip.install_common_module(target_name, module_dir) 126 | os.unlink(tf.name) 127 | return module_dir 128 | 129 | 130 | def get_version(conf_dir: str): 131 | path = os.path.join(conf_dir, "packman") 132 | if not os.path.exists(path): # in dev repo fallback 133 | path += ".sh" 134 | with open(path, "rt", encoding="utf8") as launch_file: 135 | for line in launch_file.readlines(): 136 | if "PM_PACKMAN_VERSION" in line: 137 | _, value = line.split("=") 138 | return value.strip() 139 | raise RuntimeError(f"Unable to find 'PM_PACKMAN_VERSION' in '{path}'") 140 | -------------------------------------------------------------------------------- /tools/repoman/repoman_bootstrapper.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: MIT 3 | # 4 | 5 | import json 6 | import logging 7 | import os 8 | import platform 9 | import re 10 | import sys 11 | from pathlib import Path 12 | 13 | import packmanapi 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | if sys.version_info < (3, 10): 18 | logger.warning("This version of repo_man currently requires Python 3.10 or later.") 19 | 20 | REPO_ROOT = os.path.join(os.path.dirname(os.path.normpath(__file__)), "../..") 21 | REPO_CACHE_FILE = os.path.join(REPO_ROOT, "repo-cache.json") 22 | 23 | 24 | def repoman_bootstrap(): 25 | _path_checks() 26 | _prep_cache_paths() 27 | _pull_optional_deps() 28 | 29 | 30 | def _pull_optional_deps(): 31 | """ 32 | Pull optional dependencies if repo-deps- exists as determined by _opt_deps_suffix() 33 | """ 34 | OPT_DEPS_FILE = Path(REPO_ROOT, f"deps/repo-deps-{_opt_deps_suffix()}.packman.xml") 35 | if OPT_DEPS_FILE.is_file(): 36 | deps = packmanapi.pull(OPT_DEPS_FILE.as_posix()) 37 | for dep_path in deps.values(): 38 | if dep_path not in sys.path: 39 | sys.path.append(dep_path) 40 | 41 | 42 | def _path_checks(): 43 | """Check for problematic path conditions and warn appropriately.""" 44 | cwd = os.getcwd() 45 | if " " in cwd: 46 | logger.warning( 47 | "Current working directory: %s contains whitespace which may cause issues with some tooling such as premake within repo_build. It is recommended to move your project to a path without spaces.", 48 | cwd, 49 | ) 50 | 51 | # Check if current working directory is within a OneDrive folder 52 | if platform.system() == "Windows": 53 | onedrive_path = os.getenv("OneDrive") # For personal OneDrive 54 | onedrive_business_path = os.getenv("OneDriveCommercial") # For business accounts 55 | 56 | if not onedrive_path and not onedrive_business_path: 57 | # OneDrive is not installed or synced 58 | return 59 | 60 | if (onedrive_path and cwd.startswith(onedrive_path)) or ( 61 | onedrive_business_path and cwd.startswith(onedrive_business_path) 62 | ): 63 | logger.warning( 64 | "Current working directory: %s appears to be within a OneDrive folder. This may cause filesystem issues with Packman linking dependencies. It is recommended to move your project outside of OneDrive.", 65 | cwd, 66 | ) 67 | 68 | 69 | def _prep_cache_paths(): 70 | """ 71 | There are several environment variables that repo_man can optionally set to control where various caches are placed. They will all be relative to the repository root. 72 | - PM_PACKAGES_ROOT: this is where Packman stores its package cache 73 | - PIP_CACHE_DIR: this is where pip stores its wheel cache 74 | - UV_CACHE_DIR: this is where uv stores its wheel and package cache 75 | 76 | There are several gating flags as well to prevent repo_man from using the pip/uv default cache dir envvars unless explicitly set by us. 77 | - OM_PIP_CACHE: gating pip cache dir flag for omni.repo.man.deps.pip_install_requirements 78 | - OM_UV_CACHE: gating uv cache dir flag for omni.repo.man.deps._uv_requirements_load 79 | """ 80 | 81 | repo_cache_file = Path(REPO_CACHE_FILE) 82 | if repo_cache_file.is_file(): 83 | # cache file is present, read it in and set environment variables. 84 | cache_path_data = json.loads(repo_cache_file.read_text()) 85 | # resolve REPO_ROOT rather than relative path to avoid any chdir shenanigans. 86 | resolved_root = Path(REPO_ROOT).resolve() 87 | 88 | for cache, cache_path in cache_path_data.items(): 89 | # Expand $HOME and ~ 90 | resolved_path = Path(os.path.expandvars(os.path.expanduser(cache_path))) 91 | if not resolved_path.is_dir(): 92 | # Relative path to current working directory or absolute path is not present. 93 | # It's possible repo was somehow executed outside of the repository root. 94 | resolved_path = resolved_root / cache_path 95 | 96 | # Fully resolve path to avoid weird dir popping in some workflows. 97 | os.environ[cache] = resolved_path.resolve().as_posix() 98 | resolved_path.mkdir(parents=True, exist_ok=True) 99 | 100 | # Set repo_man breadcrumb to respect PIP_CACHE_DIR and UV_CACHE_DIR. 101 | # Unset OMNI_REPO_ROOT to force the caching of installed Python deps 102 | # in the packman cache dir. 103 | if cache == "PIP_CACHE_DIR": 104 | os.environ["OM_PIP_CACHE"] = "1" 105 | os.environ["OMNI_REPO_ROOT"] = "" 106 | elif cache == "UV_CACHE_DIR": 107 | os.environ["OM_UV_CACHE"] = "1" 108 | os.environ["OMNI_REPO_ROOT"] = "" 109 | 110 | 111 | def _opt_deps_suffix(): 112 | """ 113 | We want a general ability to specify an optional set of repo-tool dependencies for internal use. 114 | Since this config must be checked for before repo_man has been bootstrapped, accessing with toml 115 | is not an option. This is invoked on every tool startup, and needs to be fast, so a very simple 116 | load-and-search is used. No config-resolution occurs at this point. 117 | 118 | This is only accessed in the repoman.py entrypoint, and should not be used anywhere else. 119 | 120 | If this value is needed later in other contexts, it can instead be gotten from the resolved config. 121 | """ 122 | 123 | opt_deps_suffix = "nv" 124 | repo_toml = Path(REPO_ROOT, "repo.toml") 125 | if repo_toml.is_file(): 126 | with open(repo_toml, "r") as f: 127 | for line in f.readlines(): 128 | line = line.lstrip() 129 | if line.startswith("optional_deps_suffix"): 130 | match = re.search(r"""optional_deps_suffix.=.['"](.+?)['"]""", line) 131 | if match: 132 | opt_deps_suffix = match.group(1) 133 | break 134 | return opt_deps_suffix 135 | -------------------------------------------------------------------------------- /source/apps/isaacsim.exp.base.zero_delay.kit: -------------------------------------------------------------------------------- 1 | [package] 2 | title = "Isaac Sim Python" 3 | description = "A trimmed down app for use with python providing zero frame delay" 4 | version = "5.1.0" 5 | execFile = "isaac-sim.zero_delay" 6 | keywords = ["experience", "app", "usd", "isaacsim"] # That makes it browsable in UI with "experience" filter 7 | 8 | 9 | [dependencies] 10 | "isaacsim.exp.base" = {} 11 | 12 | [settings] 13 | app.name = "Isaac-Sim Zero Delay" 14 | app.version = "5.1.0" 15 | app.hydraEngine.waitIdle = true 16 | app.updateOrder.checkForHydraRenderComplete = 1000 17 | app.vulkan = true # Explicitly enable Vulkan 18 | app.enableDeveloperWarnings = false # disable developer warnings to reduce log noise 19 | app.exts.isaacsim.ros2.bridge.publish_multithreading_disabled = true # disable multithreading for ros2 bridge to reduce latency 20 | 21 | [settings.app.exts.folders] 22 | '++' = [ 23 | "${app}", 24 | "${app}/../exts", 25 | "${app}/../extscache", 26 | "${app}/../extsUser", 27 | "${app}/../extsDeprecated", 28 | ] 29 | 30 | [settings.exts."omni.kit.registry.nucleus"] 31 | registries = [ 32 | { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/107/shared" }, 33 | { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" }, 34 | { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" }, 35 | ] 36 | 37 | 38 | ######################################################################################################################## 39 | # BEGIN GENERATED PART (Remove from 'BEGIN' to 'END' to regenerate) 40 | ######################################################################################################################## 41 | 42 | # Kit SDK Version: 107.3.3+production.229672.69cbf6ad.gl 43 | 44 | # Version lock for all dependencies: 45 | [settings.app.exts] 46 | enabled = [ 47 | "isaacsim.app.about-2.0.11", 48 | "isaacsim.asset.browser-1.3.23", 49 | "isaacsim.asset.importer.mjcf-2.5.13", 50 | "isaacsim.asset.importer.urdf-2.4.30", 51 | "isaacsim.core.api-4.8.0", 52 | "isaacsim.core.cloner-1.4.10", 53 | "isaacsim.core.deprecation_manager-0.2.7", 54 | "isaacsim.core.experimental.materials-0.4.0", 55 | "isaacsim.core.experimental.objects-0.4.0", 56 | "isaacsim.core.experimental.prims-0.8.1", 57 | "isaacsim.core.experimental.utils-0.3.0", 58 | "isaacsim.core.nodes-3.4.3", 59 | "isaacsim.core.prims-0.6.1", 60 | "isaacsim.core.simulation_manager-1.4.4", 61 | "isaacsim.core.throttling-2.2.2", 62 | "isaacsim.core.utils-3.5.1", 63 | "isaacsim.core.version-2.0.6", 64 | "isaacsim.cortex.behaviors-2.0.14", 65 | "isaacsim.cortex.framework-1.0.12", 66 | "isaacsim.examples.browser-0.2.1", 67 | "isaacsim.gui.components-1.2.1", 68 | "isaacsim.gui.content_browser-0.1.11", 69 | "isaacsim.gui.menu-2.4.4", 70 | "isaacsim.gui.property-1.1.3", 71 | "isaacsim.gui.sensors.icon-2.0.3", 72 | "isaacsim.replicator.behavior-1.1.16", 73 | "isaacsim.replicator.domain_randomization-1.0.16", 74 | "isaacsim.replicator.examples-1.3.6", 75 | "isaacsim.replicator.writers-1.0.17", 76 | "isaacsim.robot.manipulators-3.3.6", 77 | "isaacsim.robot.manipulators.examples-1.1.2", 78 | "isaacsim.robot.policy.examples-4.1.11", 79 | "isaacsim.robot.schema-3.6.0", 80 | "isaacsim.robot.surface_gripper-3.3.1", 81 | "isaacsim.robot.wheeled_robots-4.0.24", 82 | "isaacsim.robot_motion.lula-4.0.8", 83 | "isaacsim.robot_motion.lula_test_widget-1.0.12", 84 | "isaacsim.robot_motion.motion_generation-8.0.26", 85 | "isaacsim.sensors.camera-1.3.6", 86 | "isaacsim.sensors.physics-0.4.3", 87 | "isaacsim.sensors.physx-2.3.2", 88 | "isaacsim.sensors.rtx-15.8.4", 89 | "isaacsim.simulation_app-2.12.2", 90 | "isaacsim.storage.native-1.5.1", 91 | "isaacsim.test.docstring-1.1.0", 92 | "isaacsim.util.debug_draw-3.1.0", 93 | "omni.anim.curve.core-1.3.1", 94 | "omni.anim.graph.schema-107.3.3", 95 | "omni.anim.navigation.schema-107.3.3", 96 | "omni.convexdecomposition-107.3.26", 97 | "omni.graph.action-1.130.0", 98 | "omni.graph.action_nodes-1.50.4", 99 | "omni.graph.action_nodes_core-1.2.0", 100 | "omni.graph.nodes-1.170.10", 101 | "omni.graph.nodes_core-1.1.0", 102 | "omni.graph.scriptnode-1.50.0", 103 | "omni.graph.ui_nodes-1.50.5", 104 | "omni.graph.visualization.nodes-2.1.3", 105 | "omni.isaac.asset_browser-1.0.6", 106 | "omni.isaac.assets_check-0.3.13", 107 | "omni.isaac.cloner-1.0.7", 108 | "omni.isaac.core-4.0.7", 109 | "omni.isaac.core_archive-3.0.0", 110 | "omni.isaac.core_nodes-2.0.6", 111 | "omni.isaac.cortex-1.0.5", 112 | "omni.isaac.cortex.sample_behaviors-2.0.5", 113 | "omni.isaac.dynamic_control-2.0.7", 114 | "omni.isaac.franka-1.0.7", 115 | "omni.isaac.kit-2.0.6", 116 | "omni.isaac.lula-4.0.6", 117 | "omni.isaac.lula_test_widget-1.0.6", 118 | "omni.isaac.manipulators-3.0.7", 119 | "omni.isaac.menu-1.0.6", 120 | "omni.isaac.ml_archive-3.0.4", 121 | "omni.isaac.motion_generation-8.0.7", 122 | "omni.isaac.nucleus-1.0.6", 123 | "omni.isaac.quadruped-3.0.7", 124 | "omni.isaac.range_sensor-4.0.6", 125 | "omni.isaac.sensor-13.0.7", 126 | "omni.isaac.surface_gripper-2.0.6", 127 | "omni.isaac.universal_robots-1.0.6", 128 | "omni.isaac.utils-2.0.6", 129 | "omni.isaac.version-2.0.7", 130 | "omni.isaac.wheeled_robots-3.0.7", 131 | "omni.isaac.window.about-2.0.7", 132 | "omni.kit.asset_converter-5.0.17", 133 | "omni.kit.browser.core-2.3.13", 134 | "omni.kit.browser.folder.core-1.10.9", 135 | "omni.kit.graph.delegate.default-1.2.3", 136 | "omni.kit.graph.editor.core-1.5.3", 137 | "omni.kit.graph.usd.commands-1.3.1", 138 | "omni.kit.loop-isaac-1.3.7", 139 | "omni.kit.menu.stage-1.2.7", 140 | "omni.kit.property.isaac-1.0.6", 141 | "omni.kit.scripting-107.3.2", 142 | "omni.kit.tool.asset_importer-4.3.2", 143 | "omni.kit.viewport.menubar.lighting-107.3.1", 144 | "omni.kit.widget.material_preview-1.0.16", 145 | "omni.kit.widget.zoombar-1.0.6", 146 | "omni.kit.window.material_graph-1.9.1", 147 | "omni.kvdb-107.3.26", 148 | "omni.localcache-107.3.26", 149 | "omni.physics-107.3.26", 150 | "omni.physics.physx-107.3.26", 151 | "omni.physics.stageupdate-107.3.26", 152 | "omni.physics.tensors-107.3.26", 153 | "omni.physx-107.3.26", 154 | "omni.physx.cooking-107.3.26", 155 | "omni.physx.foundation-107.3.26", 156 | "omni.physx.tensors-107.3.26", 157 | "omni.pip.cloud-1.4.3", 158 | "omni.pip.compute-1.6.3", 159 | "omni.replicator.core-1.12.27", 160 | "omni.replicator.isaac-2.0.8", 161 | "omni.replicator.replicator_yaml-2.0.11", 162 | "omni.usd.metrics.assembler-107.3.1", 163 | "omni.usd.metrics.assembler.physics-107.3.26", 164 | "omni.usd.metrics.assembler.ui-107.3.1", 165 | "omni.usd.schema.flow-107.1.1", 166 | "omni.usd.schema.isaac-3.0.5", 167 | "omni.usd.schema.metrics.assembler-107.3.1", 168 | "omni.usd.schema.physx-107.3.26", 169 | "omni.usdphysics-107.3.26", 170 | "omni.warp-1.8.2", 171 | "omni.warp.core-1.8.2", 172 | "semantics.schema.editor-2.0.2", 173 | "semantics.schema.property-2.0.1", 174 | ] 175 | 176 | ######################################################################################################################## 177 | # END GENERATED PART 178 | ######################################################################################################################## -------------------------------------------------------------------------------- /tools/packman/bootstrap/install_package.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 NVIDIA CORPORATION 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import logging 16 | import zipfile 17 | import tempfile 18 | import sys 19 | import os 20 | import stat 21 | import time 22 | import hashlib 23 | from typing import Any, Callable, Union 24 | 25 | 26 | RENAME_RETRY_COUNT = 100 27 | RENAME_RETRY_DELAY = 0.1 28 | 29 | logging.basicConfig(level=logging.WARNING, format="%(message)s") 30 | logger = logging.getLogger("install_package") 31 | 32 | 33 | def remove_directory_item(path): 34 | if os.path.islink(path) or os.path.isfile(path): 35 | try: 36 | os.remove(path) 37 | except PermissionError: 38 | # make sure we have access and try again: 39 | os.chmod(path, stat.S_IRWXU) 40 | os.remove(path) 41 | else: 42 | # try first to delete the dir because this will work for folder junctions, otherwise we would follow the junctions and cause destruction! 43 | clean_out_folder = False 44 | try: 45 | # make sure we have access preemptively - this is necessary because recursing into a directory without permissions 46 | # will only lead to heart ache 47 | os.chmod(path, stat.S_IRWXU) 48 | os.rmdir(path) 49 | except OSError: 50 | clean_out_folder = True 51 | 52 | if clean_out_folder: 53 | # we should make sure the directory is empty 54 | names = os.listdir(path) 55 | for name in names: 56 | fullname = os.path.join(path, name) 57 | remove_directory_item(fullname) 58 | # now try to again get rid of the folder - and not catch if it raises: 59 | os.rmdir(path) 60 | 61 | 62 | class StagingDirectory: 63 | def __init__(self, staging_path): 64 | self.staging_path = staging_path 65 | self.temp_folder_path = None 66 | os.makedirs(staging_path, exist_ok=True) 67 | 68 | def __enter__(self): 69 | self.temp_folder_path = tempfile.mkdtemp(prefix="ver-", dir=self.staging_path) 70 | return self 71 | 72 | def get_temp_folder_path(self): 73 | return self.temp_folder_path 74 | 75 | # this function renames the temp staging folder to folder_name, it is required that the parent path exists! 76 | def promote_and_rename(self, folder_name): 77 | abs_dst_folder_name = os.path.join(self.staging_path, folder_name) 78 | os.rename(self.temp_folder_path, abs_dst_folder_name) 79 | 80 | def __exit__(self, type, value, traceback): 81 | # Remove temp staging folder if it's still there (something went wrong): 82 | path = self.temp_folder_path 83 | if os.path.isdir(path): 84 | remove_directory_item(path) 85 | 86 | 87 | def rename_folder(staging_dir: StagingDirectory, folder_name: str): 88 | try: 89 | staging_dir.promote_and_rename(folder_name) 90 | except OSError as exc: 91 | # if we failed to rename because the folder now exists we can assume that another packman process 92 | # has managed to update the package before us - in all other cases we re-raise the exception 93 | abs_dst_folder_name = os.path.join(staging_dir.staging_path, folder_name) 94 | if os.path.exists(abs_dst_folder_name): 95 | logger.warning( 96 | f"Directory {abs_dst_folder_name} already present, package installation already completed" 97 | ) 98 | else: 99 | raise 100 | 101 | 102 | def call_with_retry( 103 | op_name: str, func: Callable, retry_count: int = 3, retry_delay: float = 20 104 | ) -> Any: 105 | retries_left = retry_count 106 | while True: 107 | try: 108 | return func() 109 | except (OSError, IOError) as exc: 110 | logger.warning(f"Failure while executing {op_name} [{str(exc)}]") 111 | if retries_left: 112 | retry_str = "retry" if retries_left == 1 else "retries" 113 | logger.warning( 114 | f"Retrying after {retry_delay} seconds" 115 | f" ({retries_left} {retry_str} left) ..." 116 | ) 117 | time.sleep(retry_delay) 118 | else: 119 | logger.error("Maximum retries exceeded, giving up") 120 | raise 121 | retries_left -= 1 122 | 123 | 124 | def rename_folder_with_retry(staging_dir: StagingDirectory, folder_name): 125 | dst_path = os.path.join(staging_dir.staging_path, folder_name) 126 | call_with_retry( 127 | f"rename {staging_dir.get_temp_folder_path()} -> {dst_path}", 128 | lambda: rename_folder(staging_dir, folder_name), 129 | RENAME_RETRY_COUNT, 130 | RENAME_RETRY_DELAY, 131 | ) 132 | 133 | 134 | def generate_sha256_for_file(file_path: Union[str, os.PathLike]) -> str: 135 | """Returns the SHA-256 hex digest for the file at `file_path`""" 136 | hash = hashlib.sha256() 137 | # Read the file in binary mode and update the hash object with data 138 | with open(file_path, "rb") as file: 139 | for chunk in iter(lambda: file.read(4096), b""): 140 | hash.update(chunk) 141 | return hash.hexdigest() 142 | 143 | 144 | def install_common_module(package_path, install_path): 145 | COMMON_SHA256 = "b4d6e83b117224d021d89c80018f4954dcd95a4896b8bd33346bc500c712030c" 146 | package_sha256 = generate_sha256_for_file(package_path) 147 | if package_sha256 != COMMON_SHA256: 148 | raise RuntimeError( 149 | f"Package at '{package_path}' must have a sha256 of '{COMMON_SHA256}' " 150 | f"but was found to have '{package_sha256}'" 151 | ) 152 | staging_path, version = os.path.split(install_path) 153 | with StagingDirectory(staging_path) as staging_dir: 154 | output_folder = staging_dir.get_temp_folder_path() 155 | with zipfile.ZipFile(package_path, allowZip64=True) as zip_file: 156 | zip_file.extractall(output_folder) 157 | 158 | # attempt the rename operation 159 | rename_folder_with_retry(staging_dir, version) 160 | 161 | print(f"Package successfully installed to {install_path}") 162 | 163 | 164 | if __name__ == "__main__": 165 | executable_paths = os.getenv("PATH") 166 | paths_list = executable_paths.split(os.path.pathsep) if executable_paths else [] 167 | target_path_np = os.path.normpath(sys.argv[2]) 168 | target_path_np_nc = os.path.normcase(target_path_np) 169 | for exec_path in paths_list: 170 | if os.path.normcase(os.path.normpath(exec_path)) == target_path_np_nc: 171 | raise RuntimeError(f"packman will not install to executable path '{exec_path}'") 172 | install_common_module(sys.argv[1], target_path_np) 173 | -------------------------------------------------------------------------------- /tools/isaacsim/data/python_packages/isaacsim/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved. 2 | # 3 | # NVIDIA CORPORATION and its licensors retain all intellectual property 4 | # and proprietary rights in and to this software, related documentation 5 | # and any modifications thereto. Any use, reproduction, disclosure or 6 | # distribution of this software and related documentation without an express 7 | # license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | # 9 | 10 | import ctypes 11 | import glob 12 | import os 13 | import sys 14 | 15 | EXT_PATH = "extscache" 16 | DEP_EXT_PATH = "extscache" 17 | 18 | 19 | def bootstrap_kernel(): 20 | using_inner_kernel = False 21 | 22 | # isaac-sim path 23 | isaacsim_path = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) 24 | 25 | # check if it is a non-Python package manager installation 26 | split_path = isaacsim_path.split(os.sep) 27 | if len(split_path) >= 2 and split_path[-1] == "isaacsim" and split_path[-2] == "python_packages": 28 | return 29 | 30 | # kit path (internal kernel) 31 | if os.path.isdir(os.path.join(isaacsim_path, "kit", "extscore")): 32 | kit_path = os.path.join(isaacsim_path, "kit") 33 | using_inner_kernel = True 34 | # kit path (omniverse-kit kernel package) 35 | else: 36 | try: 37 | import omni.kit_app # importing 'omni.kit_app' will bootstrap kernel 38 | 39 | kit_path = os.path.dirname(os.path.abspath(os.path.realpath(omni.kit_app.__file__))) 40 | except ModuleNotFoundError: 41 | print("Unable to find 'omniverse-kit' package") 42 | exit() 43 | 44 | # preload libcarb.so 45 | if using_inner_kernel: 46 | carb_library = "carb.dll" if sys.platform == "win32" else "libcarb.so" 47 | ctypes.PyDLL(os.path.join(kit_path, carb_library), mode=ctypes.RTLD_GLOBAL) 48 | 49 | # set environment variables 50 | if not os.environ.get("CARB_APP_PATH", None): 51 | os.environ["CARB_APP_PATH"] = kit_path 52 | if not os.environ.get("EXP_PATH", None): 53 | os.environ["EXP_PATH"] = os.path.join(isaacsim_path, "apps") 54 | if not os.environ.get("ISAAC_PATH", None): 55 | os.environ["ISAAC_PATH"] = os.path.join(isaacsim_path) 56 | 57 | # set environment variables (Jupyter) 58 | if os.environ.get("JPY_PARENT_PID", None): 59 | os.environ["ISAAC_JUPYTER_PYTHON_PACKAGE"] = "1" 60 | 61 | # set PYTHONPATH 62 | paths = [] 63 | # kit 64 | if using_inner_kernel: 65 | paths += [ 66 | os.path.join(kit_path, "kernel", "py"), 67 | ] 68 | # isaac-sim 69 | paths += [ 70 | os.path.join(isaacsim_path, EXT_PATH, "isaacsim.simulation_app"), 71 | os.path.join(isaacsim_path, DEP_EXT_PATH, "omni.isaac.kit"), 72 | ] 73 | # update sys.path 74 | for path in paths: 75 | if not path in sys.path: 76 | if not os.path.exists(path): 77 | print(f"PYTHONPATH: path doesn't exist ({path})") 78 | continue 79 | sys.path.insert(0, path) 80 | 81 | # log info 82 | import carb 83 | 84 | carb.log_info(f"Isaac Sim path: {isaacsim_path}") 85 | carb.log_info(f"Kit path: {kit_path}") 86 | carb.log_info(f"Using inner kernel: {using_inner_kernel}") 87 | 88 | 89 | def expose_api(): 90 | AppFramework, SimulationApp = None, None 91 | try: 92 | # try a direct import 93 | from isaacsim.simulation_app import AppFramework, SimulationApp 94 | except ImportError: 95 | # try to import API from isaacsim/simulation_app folder instead 96 | try: 97 | # get isaacsim/simulation_app folder path 98 | isaacsim_path = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) 99 | # The isaacsim.simulation_app can include the version number 100 | pattern = os.path.join( 101 | os.environ.get("ISAAC_PATH", isaacsim_path), 102 | EXT_PATH, 103 | "isaacsim.simulation_app*", 104 | ) 105 | matching_folders = glob.glob(pattern) 106 | if matching_folders: 107 | path = matching_folders[0] # Return the first matching folder 108 | else: 109 | path = None 110 | path = os.path.join(path, "isaacsim") 111 | if os.path.exists(path): 112 | # register path 113 | sys.path.insert(0, path) 114 | # import API 115 | from simulation_app import AppFramework, SimulationApp 116 | 117 | # register module to support 'from isaacsim.simulation_app import SimulationApp' 118 | sys.modules["isaacsim.simulation_app"] = type(sys)("isaacsim.simulation_app") 119 | sys.modules["isaacsim.simulation_app.SimulationApp"] = SimulationApp 120 | sys.modules["isaacsim.simulation_app.AppFramework"] = AppFramework 121 | else: 122 | print(f"PYTHONPATH: path doesn't exist ({path})") 123 | except ImportError as e: 124 | print("IMPORT ERROR", e) 125 | pass 126 | return AppFramework, SimulationApp 127 | 128 | 129 | def main(): 130 | args = sys.argv[1:] 131 | using_inner_kernel = False 132 | 133 | # get paths 134 | # isaac-sim path 135 | isaacsim_path = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) 136 | # kit path (internal kernel) 137 | if os.path.isdir(os.path.join(isaacsim_path, "kit", "extscore")): 138 | kit_path = os.path.join(isaacsim_path, "kit") 139 | using_inner_kernel = True 140 | # kit path (omniverse-kit kernel package) 141 | else: 142 | try: 143 | import omni.kit_app # importing 'omni.kit_app' will bootstrap kernel 144 | 145 | kit_path = os.path.dirname(os.path.abspath(os.path.realpath(omni.kit_app.__file__))) 146 | except ModuleNotFoundError: 147 | print("Unable to find 'omniverse-kit' package") 148 | exit() 149 | 150 | # experience file 151 | experience = args[0] if len(args) and not args[0].startswith("-") else "omni.app.mini" 152 | experience = experience if experience.endswith(".kit") else f"{experience}.kit" 153 | if not os.path.isfile(experience): 154 | for experience_dir in [os.path.join(isaacsim_path, "apps"), os.path.join(kit_path, "apps")]: 155 | if os.path.isfile(os.path.join(experience_dir, experience)): 156 | experience = os.path.join(experience_dir, experience) 157 | if len(args) and not args[0].startswith("-"): 158 | args = args[1:] 159 | break 160 | if not os.path.isfile(experience): 161 | print(f"Invalid experience (.kit) file: {args[0] if len(args) else ''}") 162 | exit() 163 | 164 | # launch app 165 | if using_inner_kernel: 166 | sys.path.append(kit_path) 167 | from kit_app import KitApp 168 | else: 169 | from omni.kit_app import KitApp 170 | 171 | app = KitApp() 172 | app.startup([experience, "--ext-folder", os.path.join(isaacsim_path, "apps")] + args) 173 | while app.is_running(): 174 | app.update() 175 | sys.exit(app.shutdown()) 176 | 177 | 178 | bootstrap_kernel() 179 | 180 | # make isaacsim.simulation_app discoverable 181 | AppFramework, SimulationApp = expose_api() 182 | -------------------------------------------------------------------------------- /templates/extensions/basic_python_binding/template/bindings/python/{{extension_name}}/ExamplePybindBindings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. 2 | // 3 | // NVIDIA CORPORATION and its licensors retain all intellectual property 4 | // and proprietary rights in and to this software, related documentation 5 | // and any modifications thereto. Any use, reproduction, disclosure or 6 | // distribution of this software and related documentation without an express 7 | // license agreement from NVIDIA CORPORATION is strictly prohibited. 8 | // 9 | 10 | #include 11 | 12 | #include <{{ python_module_path }}/{{ object_name }}.h> 13 | #include <{{ python_module_path }}/{{ interface_name }}.h> 14 | 15 | #include 16 | 17 | CARB_BINDINGS("{{ extension_name }}.python") 18 | 19 | DISABLE_PYBIND11_DYNAMIC_CAST({{ extension_namespace }}::{{ interface_name }}) 20 | DISABLE_PYBIND11_DYNAMIC_CAST({{ extension_namespace }}::{{ object_interface_name }}) 21 | 22 | namespace 23 | { 24 | 25 | /** 26 | * Concrete bound object class that will be reflected to Python. 27 | */ 28 | class Python{{object_name}} : public {{ extension_namespace }}::{{ object_name }} 29 | { 30 | public: 31 | /** 32 | * Factory. 33 | * 34 | * @param id Id of the bound action. 35 | * 36 | * @return The bound object that was created. 37 | */ 38 | static carb::ObjectPtr create(const char* id) 39 | { 40 | // Note: It is important to construct the handler using ObjectPtr::InitPolicy::eSteal, 41 | // otherwise we end up incresing the reference count by one too many during construction, 42 | // resulting in carb::ObjectPtr instance whose wrapped object will never be destroyed. 43 | return carb::stealObject(new Python{{object_name}}(id)); 44 | } 45 | 46 | /** 47 | * Constructor. 48 | * 49 | * @param id Id of the bound object. 50 | */ 51 | Python{{object_name}}(const char* id) 52 | : {{ object_name }}(id) 53 | , m_memberInt(0) 54 | , m_memberBool(false) 55 | , m_memberString() 56 | { 57 | } 58 | 59 | // To deomnstrate binding a fuction that accepts an argument. 60 | void multiplyIntProperty(int value) 61 | { 62 | m_memberInt *= value; 63 | } 64 | 65 | // To deomnstrate binding a fuction that returns a value. 66 | bool toggleBoolProperty() 67 | { 68 | m_memberBool = !m_memberBool; 69 | return m_memberBool; 70 | } 71 | 72 | // To deomnstrate binding a fuction that accepts an argument and returns a value. 73 | const char* appendStringProperty(const char* value) 74 | { 75 | m_memberString += value; 76 | return m_memberString.c_str(); 77 | } 78 | 79 | // To deomnstrate binding properties using accessors. 80 | const char* getMemberString() const 81 | { 82 | return m_memberString.c_str(); 83 | } 84 | 85 | // To deomnstrate binding properties using accessors. 86 | void setMemberString(const char* value) 87 | { 88 | m_memberString = value; 89 | } 90 | 91 | // To deomnstrate binding properties directly. 92 | int m_memberInt; 93 | bool m_memberBool; 94 | 95 | private: 96 | // To deomnstrate binding properties using accessors. 97 | std::string m_memberString; 98 | }; 99 | 100 | // Define the pybind11 module using the same name specified in premake5.lua 101 | PYBIND11_MODULE({{ library_name }}, m) 102 | { 103 | using namespace {{ extension_namespace }} 104 | ; 105 | 106 | m.doc() = "pybind11 {{ extension_name }} bindings"; 107 | 108 | carb::defineInterfaceClass<{{ interface_name }}>( 109 | m, "{{ interface_name }}", "acquire_bound_interface", "release_bound_interface") 110 | .def("register_bound_object", &{{ interface_name }}::register{{object_name}}, 111 | R"( 112 | Register a bound object. 113 | 114 | Args: 115 | object: The bound object to register. 116 | )", 117 | py::arg("object")) 118 | .def("deregister_bound_object", &{{ interface_name }}::deregister{{object_name}}, 119 | R"( 120 | Deregister a bound object. 121 | 122 | Args: 123 | object: The bound object to deregister. 124 | )", 125 | py::arg("object")) 126 | .def("find_bound_object", &{{ interface_name }}::find{{object_name}}, py::return_value_policy::reference, 127 | R"( 128 | Find a bound object. 129 | 130 | Args: 131 | id: Id of the bound object. 132 | 133 | Return: 134 | The bound object if it exists, an empty object otherwise. 135 | )", 136 | py::arg("id")) 137 | /**/; 138 | 139 | py::class_<{{ object_interface_name }}, carb::ObjectPtr<{{ object_interface_name }}>>(m, "{{ object_interface_name }}") 140 | .def_property_readonly("id", &{{ object_interface_name }}::getId, py::return_value_policy::reference, 141 | R"( 142 | Get the id of this bound object. 143 | 144 | Return: 145 | The id of this bound object. 146 | )") 147 | /**/; 148 | 149 | py::class_>(m, "{{object_name}}") 150 | .def(py::init([](const char* id) { return Python{{object_name}}::create(id); }), 151 | R"( 152 | Create a bound object. 153 | 154 | Args: 155 | id: Id of the bound object. 156 | 157 | Return: 158 | The bound object that was created. 159 | )", 160 | py::arg("id")) 161 | .def_readwrite("property_int", &Python{{object_name}}::m_memberInt, 162 | R"( 163 | Int property bound directly. 164 | )") 165 | .def_readwrite("property_bool", &Python{{object_name}}::m_memberBool, 166 | R"( 167 | Bool property bound directly. 168 | )") 169 | .def_property("property_string", &Python{{object_name}}::getMemberString, &Python{{object_name}}::setMemberString, py::return_value_policy::reference, 170 | R"( 171 | String property bound using accessors. 172 | )") 173 | .def("multiply_int_property", &Python{{object_name}}::multiplyIntProperty, 174 | R"( 175 | Bound fuction that accepts an argument. 176 | 177 | Args: 178 | value_to_multiply: The value to multiply by. 179 | )", 180 | py::arg("value_to_multiply")) 181 | .def("toggle_bool_property", &Python{{object_name}}::toggleBoolProperty, 182 | R"( 183 | Bound fuction that returns a value. 184 | 185 | Return: 186 | The toggled bool value. 187 | )") 188 | .def("append_string_property", &Python{{object_name}}::appendStringProperty, py::return_value_policy::reference, 189 | R"( 190 | Bound fuction that accepts an argument and returns a value. 191 | 192 | Args: 193 | value_to_append: The value to append. 194 | 195 | Return: 196 | The new string value. 197 | )", 198 | py::arg("value_to_append")) 199 | /**/; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /tools/packman/bootstrap/configure.bat: -------------------------------------------------------------------------------- 1 | :: Copyright 2019-2023 NVIDIA CORPORATION 2 | :: 3 | :: Licensed under the Apache License, Version 2.0 (the "License"); 4 | :: you may not use this file except in compliance with the License. 5 | :: You may obtain a copy of the License at 6 | :: 7 | :: http://www.apache.org/licenses/LICENSE-2.0 8 | :: 9 | :: Unless required by applicable law or agreed to in writing, software 10 | :: distributed under the License is distributed on an "AS IS" BASIS, 11 | :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | :: See the License for the specific language governing permissions and 13 | :: limitations under the License. 14 | 15 | set PM_PACKMAN_VERSION=7.31 16 | 17 | :: Specify where packman command is rooted 18 | set PM_INSTALL_PATH=%~dp0.. 19 | 20 | :: The external root may already be configured and we should do minimal work in that case 21 | if defined PM_PACKAGES_ROOT goto ENSURE_DIR 22 | 23 | :: If the folder isn't set we assume that the best place for it is on the drive that we are currently 24 | :: running from 25 | set PM_DRIVE=%CD:~0,2% 26 | 27 | set PM_PACKAGES_ROOT=%PM_DRIVE%\packman-repo 28 | 29 | :: We use *setx* here so that the variable is persisted in the user environment 30 | echo Setting user environment variable PM_PACKAGES_ROOT to %PM_PACKAGES_ROOT% 31 | setx PM_PACKAGES_ROOT %PM_PACKAGES_ROOT% 32 | if %errorlevel% neq 0 ( goto ERROR ) 33 | 34 | :: The above doesn't work properly from a build step in VisualStudio because a separate process is 35 | :: spawned for it so it will be lost for subsequent compilation steps - VisualStudio must 36 | :: be launched from a new process. We catch this odd-ball case here: 37 | if defined PM_DISABLE_VS_WARNING goto ENSURE_DIR 38 | if not defined VSLANG goto ENSURE_DIR 39 | echo The above is a once-per-computer operation. Unfortunately VisualStudio cannot pick up environment change 40 | echo unless *VisualStudio is RELAUNCHED*. 41 | echo If you are launching VisualStudio from command line or command line utility make sure 42 | echo you have a fresh launch environment (relaunch the command line or utility). 43 | echo If you are using 'linkPath' and referring to packages via local folder links you can safely ignore this warning. 44 | echo You can disable this warning by setting the environment variable PM_DISABLE_VS_WARNING. 45 | echo. 46 | 47 | :: Check for the directory that we need. Note that mkdir will create any directories 48 | :: that may be needed in the path 49 | :ENSURE_DIR 50 | if not exist "%PM_PACKAGES_ROOT%" ( 51 | echo Creating packman packages cache at %PM_PACKAGES_ROOT% 52 | mkdir "%PM_PACKAGES_ROOT%" 53 | ) 54 | if %errorlevel% neq 0 ( goto ERROR_MKDIR_PACKAGES_ROOT ) 55 | 56 | :: The Python interpreter may already be externally configured 57 | if defined PM_PYTHON_EXT ( 58 | set PM_PYTHON=%PM_PYTHON_EXT% 59 | goto PACKMAN 60 | ) 61 | 62 | set PM_PYTHON_VERSION=3.10.18-nv1-windows-x86_64 63 | set PM_PYTHON_BASE_DIR=%PM_PACKAGES_ROOT%\python 64 | set PM_PYTHON_DIR=%PM_PYTHON_BASE_DIR%\%PM_PYTHON_VERSION% 65 | set PM_PYTHON=%PM_PYTHON_DIR%\python.exe 66 | 67 | if exist "%PM_PYTHON%" goto PACKMAN 68 | if not exist "%PM_PYTHON_BASE_DIR%" call :CREATE_PYTHON_BASE_DIR 69 | 70 | set PM_PYTHON_PACKAGE=python@%PM_PYTHON_VERSION%.cab 71 | for /f "delims=" %%a in ('powershell -ExecutionPolicy ByPass -NoLogo -NoProfile -File "%~dp0\generate_temp_file_name.ps1"') do set TEMP_FILE_NAME=%%a 72 | set TARGET=%TEMP_FILE_NAME%.zip 73 | call "%~dp0fetch_file_from_packman_bootstrap.cmd" %PM_PYTHON_PACKAGE% "%TARGET%" 74 | if %errorlevel% neq 0 ( 75 | echo !!! Error fetching python from CDN !!! 76 | goto ERROR 77 | ) 78 | 79 | for /f "delims=" %%a in ('powershell -ExecutionPolicy ByPass -NoLogo -NoProfile -File "%~dp0\generate_temp_folder.ps1" -parentPath "%PM_PYTHON_BASE_DIR%"') do set TEMP_FOLDER_NAME=%%a 80 | echo Unpacking Python interpreter ... 81 | "%SystemRoot%\system32\expand.exe" -F:* "%TARGET%" "%TEMP_FOLDER_NAME%" 1> nul 82 | del "%TARGET%" 83 | :: Failure during extraction to temp folder name, need to clean up and abort 84 | if %errorlevel% neq 0 ( 85 | echo !!! Error unpacking python !!! 86 | call :CLEAN_UP_TEMP_FOLDER 87 | goto ERROR 88 | ) 89 | 90 | :: If python has now been installed by a concurrent process we need to clean up and then continue 91 | if exist "%PM_PYTHON%" ( 92 | call :CLEAN_UP_TEMP_FOLDER 93 | goto PACKMAN 94 | ) 95 | 96 | :: Clean out broken PM_PYTHON_DIR if it exists 97 | if exist "%PM_PYTHON_DIR%" ( 98 | call :REMOVE_DIR "%PM_PYTHON_DIR%" 99 | if errorlevel 1 ( 100 | call :CLEAN_UP_TEMP_FOLDER 101 | goto ERROR 102 | ) 103 | ) 104 | 105 | :: Perform atomic move (allowing overwrite, /y) 106 | move /y "%TEMP_FOLDER_NAME%" "%PM_PYTHON_DIR%" 1> nul 107 | :: Verify that python.exe is now where we expect 108 | if exist "%PM_PYTHON%" goto PACKMAN 109 | 110 | :: Wait a second and try again (can help with access denied weirdness) 111 | timeout /t 1 /nobreak 1> nul 112 | move /y "%TEMP_FOLDER_NAME%" "%PM_PYTHON_DIR%" 1> nul 113 | if %errorlevel% neq 0 ( 114 | echo !!! Error moving python %TEMP_FOLDER_NAME% -> %PM_PYTHON_DIR% !!! 115 | call :CLEAN_UP_TEMP_FOLDER 116 | goto ERROR 117 | ) 118 | 119 | :PACKMAN 120 | :: The packman module may already be externally configured 121 | if defined PM_MODULE_DIR_EXT ( 122 | set PM_MODULE_DIR=%PM_MODULE_DIR_EXT% 123 | ) else ( 124 | set PM_MODULE_DIR=%PM_PACKAGES_ROOT%\packman-common\%PM_PACKMAN_VERSION% 125 | ) 126 | 127 | set PM_MODULE=%PM_MODULE_DIR%\run.py 128 | 129 | if exist "%PM_MODULE%" goto END 130 | 131 | :: Clean out broken PM_MODULE_DIR if it exists 132 | if exist "%PM_MODULE_DIR%" ( 133 | call :REMOVE_DIR "%PM_MODULE_DIR%" 134 | if errorlevel 1 goto :ERROR 135 | ) 136 | 137 | set PM_MODULE_PACKAGE=packman-common@%PM_PACKMAN_VERSION%.zip 138 | for /f "delims=" %%a in ('powershell -ExecutionPolicy ByPass -NoLogo -NoProfile -File "%~dp0\generate_temp_file_name.ps1"') do set TEMP_FILE_NAME=%%a 139 | set TARGET=%TEMP_FILE_NAME% 140 | call "%~dp0fetch_file_from_packman_bootstrap.cmd" %PM_MODULE_PACKAGE% "%TARGET%" 141 | if %errorlevel% neq 0 ( 142 | echo !!! Error fetching packman from CDN !!! 143 | goto ERROR 144 | ) 145 | 146 | echo Unpacking ... 147 | "%PM_PYTHON%" -S -s -u -E "%~dp0\install_package.py" "%TARGET%" "%PM_MODULE_DIR%" 148 | if %errorlevel% neq 0 ( 149 | echo !!! Error unpacking packman !!! 150 | goto ERROR 151 | ) 152 | 153 | del "%TARGET%" 154 | 155 | goto END 156 | 157 | :ERROR_MKDIR_PACKAGES_ROOT 158 | echo Failed to automatically create packman packages repo at %PM_PACKAGES_ROOT%. 159 | echo Please set a location explicitly that packman has permission to write to, by issuing: 160 | echo. 161 | echo setx PM_PACKAGES_ROOT {path-you-choose-for-storing-packman-packages-locally} 162 | echo. 163 | echo Then launch a new command console for the changes to take effect and run packman command again. 164 | exit /B %errorlevel% 165 | 166 | :REMOVE_DIR 167 | rd /s /q "%~1" > nul 168 | if exist "%~1" ( 169 | echo !!! Error removing corrupt directory %~1 !!! 170 | echo !!! Please remove this path manually !!! 171 | exit /B 1 172 | ) 173 | exit /B 0 174 | 175 | :ERROR 176 | echo !!! Failure while configuring local machine :( !!! 177 | exit /B 1 178 | 179 | :CLEAN_UP_TEMP_FOLDER 180 | rd /S /Q "%TEMP_FOLDER_NAME%" > nul 181 | if exist "%TEMP_FOLDER_NAME%" ( 182 | echo !!! Error removing temporary directory %TEMP_FOLDER_NAME% !!! 183 | exit /B 1 184 | ) 185 | exit /B 0 186 | 187 | :CREATE_PYTHON_BASE_DIR 188 | :: We ignore errors and clean error state - if two processes create the directory one will fail which is fine 189 | md "%PM_PYTHON_BASE_DIR%" > nul 2>&1 190 | exit /B 0 191 | 192 | :END 193 | --------------------------------------------------------------------------------