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 does a good job of deep-copying symbolic links. Note that in this case the simple project is located in the C:\tmp\OmniUSDReader directory
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
Note that in this case the simple project is located in the ~/OmniUSDReader directory
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

Visual Studio Linker Options
  1. Additional Library Directories:

    • Debug

      • deps\usd\debug\lib;deps\omni_client_library\debug

    • Release

      • deps\usd\release\lib;deps\omni_client_library\release

  2. 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

Visual Studio C++ Options
  1. Additional Options (to silence warnings):

    • /wd4244 /wd4305

  2. 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

  3. 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.

Visual Studio C++ Options
  1. 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:

  1. Put the runtime dependencies - omniclient.dll, omni_spectree.dll, and friends - in the application’s CWD or executable directory

  2. Add the runtime dependencies’ directory to the PATH environment variable

  3. Use 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 against python3.lib

    • This is using the pragma comment(lib,"python3.lib") directive, so it doesn’t need to be in the build config

  • On Windows the USD package includes python3.lib in deps\usd\$(config)\lib

  • On Linux the USD package does NOT include these Python headers or libraries