Building and Deploying a Connector Overview
This section describes how to create a simple application that will open a USD stage located on an Omniverse Nucleus server based on the USD and Omniverse Client Libraries retrieved from the Connect Sample. Once the stage is open it will simply report the stage up-axis, the stage linear units, and list all of the prim node paths. Note that a Connector may be comprised of an “application”, but is typically a plugin that runs in the context of a content creation tool. In addition to an “application”, these same concepts could be used to build a converter.
This section describes the steps necessary for both Windows and Linux.
Visual Studio (Windows)
Create a new Visual Studio project based on the C++ Console App
, Empty Project
template. After successfully setting everything up and building the folder structure might look something like this, just to give a general idea of where things go:
PROJECT_FOLDER ├── deps │ └── omni_client_library │ └── omni_usd_resolver │ └── usd ├── scripts │ └── copy_binary_deps.bat ├── x64 (where Visual Studio will probably output the executables) │ └── Release │ └── OmniUSDReader.exe │ └── *.dll (lots of required DLLs for Omniverse and USD) └── OmniUSDReader.cpp
Makefile (Linux)
The Makefile to build OmniUSDReader is available in with the Connect Sample under /source/omniUsdReader/scripts/Makefile
. It lays out some of the minimum include and library directories, library dependencies, and build settings.
Dependencies for Omniverse Client Library and USD
The Omniverse Client Library, Omniverse USD Resolver Plugin, and OpenUSD are required, so the first thing to do is to copy them into the project structure of the simple app.
From the Connect Sample root folder, these folders should be copied after the dependencies are fetched.
To fetch dependencies, use repo.bat build --stage
on Windows and ./repo.sh build --stage
on Linux.
_build\target-deps\usd
_build\target-deps\omni_client_library
_build\target-deps\omni_usd_resolver
_build\target-deps\python (Linux)
These dependencies contain symbolic links, so care must be taken when copying them into the simple app’s folders. The deps
folder will hold the USD and Client Library dependencies for the application. Here are some command lines that can be run from within the Connect Sample’s root folder:
robocopy /S _build\target-deps\omni_client_library C:\tmp\OmniUSDReader\deps\omni_client_library
robocopy /S _build\target-deps\omni_usd_resolver C:\tmp\OmniUSDReader\deps\omni_usd_resolver
robocopy /S _build\target-deps\usd C:\tmp\OmniUSDReader\deps\usd
cp -Lr _build/target-deps/omni_client_library ~/OmniUSDReader/deps/omni_client_library
cp -Lr _build/target-deps/omni_usd_resolver ~/OmniUSDReader/deps/omni_usd_resolver
cp -Lr _build/target-deps/usd ~/OmniUSDReader/deps/usd
cp -Lr _build/target-deps/python ~/OmniUSDReader/deps/python
Visual Studio Project Settings (Windows)
Because this application uses USD that means it uses Boost and TBB which require libraries, preprocessor definitions, and additional options. Also note that we only provide the 64 bit x64 platform binaries, so don’t try to build for the 32 bit platform in Visual Studio when you generate a new console project (for this example at least).
Linker Settings
Additional Library Directories:
Debug
deps\usd\debug\lib;deps\omni_client_library\debug
Release
deps\usd\release\lib;deps\omni_client_library\release
Additional Dependencies:
Debug and Release (note that as more of the USD library is used, more dependencies are required beyond this set)
sdf.lib;tf.lib;usd.lib;usdGeom.lib;omniclient.lib
C/C++ Compiler Settings
Additional Options (to silence warnings):
/wd4244 /wd4305
Additional Include Directories (Note: OpenUSD includes Boost and TBB include directories, so they need not be specified):
Debug
deps\usd\debug\include;deps\omni_client_library\include
Release
deps\usd\release\include;deps\omni_client_library\include
Preprocessor Definitions:
Debug
BOOST_ALL_DYN_LINK;NOMINMAX
Release
BOOST_ALL_DYN_LINK;NOMINMAX
Post-build Event to Copying Runtime Dependencies
There are a lot of runtime dependencies, to make things easy they are simply copied to the same folder as the output executable. A batch file that runs after the app is built makes this convenient and free of errors.
Post-Build Event:
Debug
scripts\copy_binary_deps.bat debug $(OutputPath)
Release
scripts\copy_binary_deps.bat release $(OutputPath)
The copy_binary_deps.bat
script is run after each build and puts the runtime dependencies in the correct place. It should be copied into the project’s scripts
folder. It is available in the Connect Sample under /source/omniUsdReader/scripts/copy_binary_deps.bat
.
Running OmniUSDReader
To run OmniUSDReader
on Linux, it must be run from within the target directory or with LD_LIBRARY_PATH
set to include the target directory. For an example of how to do this, refer to any of the sample run_*.sh
scripts.
Simple App Overview
The application performs a few simple things:
Expects one argument, the path to a USD stage
Acceptable forms:
omniverse://localhost/Users/test/helloworld.usd
C:/USD/helloworld.usd
A relative path based on the CWD of the program (
helloworld.usd
)Initialize Omniverse
Set the Omniverse Client log callback
Set the Omniverse Client log level
Initialize the Omniverse Client library
Register an Omniverse Client status callback
Open the USD stage
Print the stage’s up-axis
Print the stage’s linear units, or “meters per unit” setting
Traverse the stage prims and print the path of each one
Destroy the stage object
Shutdown the Omniverse Client library
OmniUSDReader.cpp
The OmniUSDReader source is available in with the Connect Sample under /source/omniUsdReader/OmniUSDReader.cpp
OpenUSD, Omniverse, and Python Runtime Dependencies
This is an outline of the files that are required at runtime for both Windows and Linux:
TARGET_FOLDER
├── bindings-python
│ ├── omni
│ | ├── client - Python bindings for the Omniverse Client Library
│ | ├── spectree - Python bindings for the Omniverse Client Library SpecTree library (required by the Client Library)
│ | ├── use_resolver - Python bindings for the Omniverse USD Resolver Plugin
├── python
│ └── pxr
│ └── ... - Python bindings for the various USD plugins
├── usd
| └── ... - USD Plugin definitions
├── ar.dll - The USD Asset Resolver plugin
├── [USD plugin name].dll - Note that the USD plugins are implemented as shared libraries and must be present if used by the Connector
├── boost_python*.dll - The one required boost shared library
├── carb.dll - Omniverse Carbonite (required by the Client Library)
├── omniclient.dll - Omniverse Client Library
├── omni*.dll - Omniverse Client Library and USD Resolver plugin dependencies
├── omni_usd_resolver.dll - Omniverse USD Resolver plugin
├── python*.dll - Python Core
├── tbb*.dll - TBB
|── usd*.dll - USD plugins
|── vcruntime*.dll - Microsoft C Runtime Library
└── OmniUSDReader.exe - The App/Connector/Converter built in this exercise
TARGET_FOLDER
├── bindings-python
│ ├── omni
│ | ├── client - Python bindings for the Omniverse Client Library
│ | ├── spectree - Python bindings for the Omniverse Client Library SpecTree library (required by the Client Library)
│ | ├── use_resolver - Python bindings for the Omniverse USD Resolver Plugin
├── python
│ └── pxr
│ └── ... - Python bindings for the various USD plugins
├── usd
| └── ... - USD Plugin definitions
├── libar.so* - The USD Asset Resolver plugin
├── lib[USD plugin name].so* - Note that the USD plugins are implemented as shared libraries and must be present if used by the Connector
├── libboost_python*.so* - The one required boost shared library
├── libcarb.so* - Omniverse Carbonite (required by the Client Library)
├── libomniclient.so* - Omniverse Client Library
├── libomni*.so* - Omniverse Client Library and USD Resolver plugin dependencies
├── libomni_usd_resolver.so* - Omniverse USD Resolver plugin
├── libpython*.so* - Python Core
├── libtbb*.so* - TBB
|── libusd*.so* - USD plugins
└── OmniUSDReader - The App/Connector/Converter built in this exercise
Omniverse Module Runtime Dependencies (Windows)
It’s important when initializing the Omniverse USD Resolver plugins, the Omniverse Live file format plugin requires at least two DLLs, omniclient.dll
, and omni_spectree.dll
to be discoverable. Connectors will typically link against omniclient.dll
already, so it’s quite possible that this will be loaded, but the directory that contains omni_spectree.dll
must be in the DLL search path. The typical way to do this is to do one of these things:
Put the runtime dependencies -
omniclient.dll
,omni_spectree.dll
, and friends - in the application’s CWD or executable directoryAdd the runtime dependencies’ directory to the
PATH
environment variableUse SetDllDirectory() or AddDllDirectory() before initializing the Omniverse USD Resolver plugins
Python Build Dependencies
Python include files and libraries are required to build this example, but there’s a distinction between Windows and Linux. On Windows, the OpenUSD package includes both the Python include files and Python libraries. On Linux, the Open USD package does NOT contain Python include files and Python libraries and the steps above specify that the Python dependency folder be copied into the example Connector build directories.
As demonstrated above in the Visual Studio project files and Makefile:
On Windows the Python header bundled with the USD package,
deps\usd\$(config)\include\python\pyconfig.h
, explicitly links againstpython3.lib
This is using the
pragma comment(lib,"python3.lib")
directive, so it doesn’t need to be in the build configOn Windows the USD package includes
python3.lib
indeps\usd\$(config)\lib
On Linux the USD package does NOT include these Python headers or libraries