============================== Connect Sample ============================== .. image:: /content/images/connect_sample_helloworld.png :align: center :alt: The stage created by the HelloWorld Sample Overview ------------------- Build your own |nv| |omni| |connector_short| by following our samples that use Pixar USD and |omni| Client Library APIs. You can download the prebuilt Samples for Windows and Linux from the |launcher_short| by searching for "Connect Sample". Once downloaded, you can directly run each sample using the provided ``run_*.bat`` files (or ``run_*.sh`` on Linux). See below for :ref:`detailed explanations` of each sample. Alternatively, you can build from source by running ``.\build.bat`` (or ``./build.sh`` on Linux) which will download the prebuilt USD and |omni| dependencies and re-compile the samples. .. Note:: On Windows this will automatically generate the Visual Studio solution file and build it. If you are interested in what dependencies are necessary to build your own Connector, examine either the ``premake5.lua`` build configuration file, the xml files in the ``deps`` folder, or the output files in the ``_compiler`` folder. This is a summary of the main things provided by the Connect Sample: * C++ and Python samples for working with USD and MDL on Nucleus * Omniverse and USD HelloWorld * Live Session * Live Sensors * C++ classes and Python module utilities * Unified handling of USD transforms * USD Prim and Layer utilities * UsdLuxLight Schema/API compatibility * Live Session channel, config, etc classes * C++ OmniCLI that exercises the Omniverse Client Library interfaces * File/Folder copy * Logging * Other client utilities * A distribution mechanism for * NV USD 20.08 (and more) * Omniverse USD Resolver and File Format Plugins * Omniverse Client Library * Omniverse Asset Validator This diagram is an overview of the components that we distribute in the Connect Sample and how an Omniverse Connector might use them: .. image:: /content/images/connect_sample_component_overview.png :align: center :alt: The stage created by the HelloWorld Sample .. _sampleDetails: Sample Details ------------------- - :ref:`Omni Asset Validator` - A command line USD validation tool. - :ref:`Omni CLI` - A command line utility to manage files on a Nucleus server. - :ref:`HelloWorld (C++ and Python)` - A sample program that shows how to connect to an Omniverse Nucleus server, create a USD stage, create a polygonal box, bind a material, add a light, save data to .usd file, create and edit a .live layer, and send/receive messages over a channel on Nucleus. This sample is provided in both C++ and Python to demonstrate the |omni| APIs for each language. - :ref:`LiveSession (C++ and Python)` - A sample program that demonstrates how to create, join, merge, and participate in live sessions. This sample is provided in both C++ and Python to demonstrate the |omni| APIs for each language. - :ref:`OmniUsdaWatcher (C++)` - A live USD watcher that outputs a constantly updating USDA file on disk. - :ref:`OmniSimpleSensor (C++)` - A C++ program that demonstrates how to connect external input (e.g sensor data) to a USD layer in Nucleus. .. _omniassetvalidator: Omni Asset Validator #################### :guilabel:`Introduced in 201.0` A command line USD validation tool (``omni_asset_validator.bat|sh``). The |omni| Asset Validator is a python framework to provide ``Usd.Stage`` validation based on the `USD ComplianceChecker `_ (i.e. the same backend as the usdchecker commandline tool), with an aim to validate assets against Omniverse specific rules to ensure they run smoothly across all Omniverse products. `Complete Asset Validator Documentation `_ The asset validator may also be run against stages in-memory. This is demonstrated in the Python version of the LiveSession example with the ``v`` option. .. _omnicli: Omni CLI ################# A command line utility to manage files on a Nucleus Server (``omnicli.bat|sh``). This program was initially created to exercise most of the |omni| Client Library API, but has grown to be a useful utility to interact with |nuc_short| servers. Typing ``help`` will produce a menu that shows the many functions available. Among the most useful are the move/copy functions which can transfer data to and from servers. .. _helloWorld: HelloWorld (C++ and Python) ########################### A sample program that creates a USD stage on a Nucleus server (``run_hello_world.bat|sh`` or ``run_py_hello_world.bat|sh``). The sample demonstrates how to: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * connect to an |omni| server * create a USD stage * create a physics scene to define simulation parameters * create a polygonal box and add it to the stage and make it a dynamic rigid * create a cube and add it to the stage and make it a dynamic rigid * create a quad and add it to the stage and make it a collider * upload an MDL material and its textures to an |omni| server * bind an MDL and USD Preview Surface material to the box * add a distant and dome light to the stage * create |nuc_short| checkpoints * move and rotate the box with live updates * disconnect from an |omni| server * print verbose Omniverse logs * open an existing stage and find a mesh to do live edits * send and receive messages over a channel on an |omni| server .. _liveSession: LiveSession (C++ and Python) ############################ A sample program that demonstrates how to create, join, merge, and participate in live sessions (``run_live_session.bat|sh`` or ``run_py_live_session.bat|sh``). A .live layer is used in the stage's session layer to contain the changes. An Omniverse channel is used to broadcast users and merge notifications to all clients, and a session config (TOML) file is used to determine the "owner" of the session. The sample demonstrates how to: * Initialize the Omniverse Resolver Plugin * Display existing live sessions for a stage * Connect to a live session * Set the edit target to the .live layer so changes replicate to other clients * Make xform changes to a mesh prim in the .live layer * Rename a prim in the .live layer * Display the owner of the live session * Display the current connected users/peers in the session * Emit a GetUsers message to the session channel * Display the contents of the session config * Validate a stage using the |omni| Asset Validator (Python example only) * Merge the changes from the .live session back to the root stage * Respond (by exiting) when another user merges session changes back to the root stage .. _usdaWatcher: OmniUSDAWatcher (C++) ###################### The Omniverse USDA Watcher is a command line program that keeps an updated USDA file on local disk that maps to a USD resident on a Nucleus server (``run_omniUsdaWatcher.bat|sh``). It takes two arguments, the USD layer to watch and the output USDA layer: * Acceptable forms * URL: ``omniverse://localhost/Users/test/helloworld.usd`` * URL: ``C:\USD\helloworld.usda`` * A local file path using shell variables: ``~\helloworld.usda`` * A relative path based on the CWD of the program: ``helloworld.usda`` The "watcher" demonstrates how to: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Initialize Omniverse * Set the Omniverse Client log callback (using a lambda) * Set the Omniverse Client log level * Initialize the Omniverse Client library * Register a connection status callback * Set the USD stage URL as live * Open the USD stage * Create and register the Sdf layer reload, layer change, and USD notice listeners * Subscribe to file changes with omniClientStatSubscribe * Start a thread that loops, receiving live changes from other clients * When the stage is modified it's written out to the specified USDA * The main thread loops on keyboard input, waiting for a 'q' or ESC * Cleanup the callbacks (unsubscribe and revoke) * Destroy the stage object * Shutdown the Omniverse Client library For example, to monitor the stage that the HelloWorld sample creates by default: ``run_omniUsdaWatcher.bat omniverse://localhost/Users/test/helloworld.usd C:\USD\helloworld.usda`` .. image:: /content/images/connect_sample_usd_watcher.png :align: center :alt: OmniUsdaWatcher in action :width: 640px .. _simpleSensor: OmniSimpleSensor (C++) ###################### The Omniverse Simple Sensor example demonstrates how to connect external input (e.g sensor data) to a USD layer in Nucleus(``run_omniSimpleSensor.bat|sh``). This could effectively be a large number of inputs that report current values for IoT sensors or could be locations from robots and a real-time synchronization of the data in the virtual world is desired. It takes three arguments, the Nucleus server path, the number of inputs and a timeout value. ``run_OmniSimpleSensor.bat `` * Acceptable forms * Server Path: ``omniverse://localhost/Users/test`` (a location on a Nucleus server) * Number of Inputs: ``4`` (integer value of 1 to any number) * Timeout: ``-1 or 20`` (-1 is for infinity to run until killed, otherwise a number in seconds) For example, ``run_OmniSimpleSensor.bat omniverse://localhost/Users/test 27 -1`` There are two parts to this project. OmniSimpleSensor will build a USD with a number of boxes (meshes) on one layer. * Initialize Omniverse * Check for an existing SimpleSensorExample.usd stage at the location, if it exists, delete it * Create SimpleSensorExample.usd at * Build a simple array of box meshes, starting with /World/Box_0 then /World/Box_1 and so on * Save the USD * Destroy the stage object * Shutdown the Omniverse Client library OmniSensorThread is then started for each 'input' specified in the command line. * Initialize Omniverse * Open SimpleSensorExample.usd at * Find the box mesh in USD this process will change * Create a worker thread to update the box's color every 300ms * In the main loop, wait until the timeout occurs, then * Stop the worker thread * Destroy the stage object * Shutdown the Omniverse Client library For example, if 6 inputs are asked for then there will be 6 OmniSensorThread processes running, independently of each other. The OmniSensorThread will launch a thread that will update the color of its assigned box at a given frequency (300ms in the code, but this can be altered). Opening the stage (look for SimpleSensorExample.usd in the Nucleus location specified) and turning on Live mode in Create or View, the boxes will be changing colors at some regular intervals. This project can easily be extended to change the transform of the boxes or to add some metadata with a custom string attached to the USD or do change visibility states. Some things to note here: * Using separate processes for each input, allows the USD to be changed independently * This example could be re-written to have one main process and a bunch of worker threads launched for each input. In this case, there would be a need to use a mutex when writing data to Nucleus through one Omni Client Library instance (there is one instance per process). This will ensure that the writing to USD via the Omni Client Library resource is dedicated. Keeping the mutex around the smallest bit of code writing to USD is recommended in this case to prevent thread starvation (especially when the frequency of input is high). * Reading USD via Omni Client Library does not have this issue and multiple threads in the same process can read from a USD, even the same layer in USD, without a mutex. .. image:: /content/images/connect_sample_simplesensor_diagram.png :align: center :alt: Connection Paths of the Simple Sensor Example :width: 640px Omniverse Client Library and Live Sessions ------------------------------------------ :guilabel:`Introduced in 200.0` The Connect Samples version 200.0 includes a large update to the Omniverse Client Library version 2. This change impacts Connectors in these ways: * Omniverse dependencies are retrieved differently * The USD Resolver may need to be initialized separately * API changes * Live sync changes * USD version changes The biggest changes are centered around live sync and USD versions. First, live sync no longer works on .usd files, but is now restricted only to .live files, which we'll refer to as .live layers. This change to using .live layers allows Omniverse to start live sessions without changing the underlying data. Clients will typically use USD layer composition with the edit target set to the .live layer to enable live synchronization in a USD stage. Note: .live layers are presented to clients as USD layers. More USD library versions are now supported due to changes in the Client Library and USD Resolver plugin because they can now compile against stock USD. See the `Omniverse Live Workflow Documentation <../../prod_extensions/prod_extensions/ext_live.html>`__ for more information on the UI/UX for implementing and using Live Sessions in Create and other clients. See the `Omniverse Live Workflow Developer FAQ <../../prod_extensions/prod_extensions/ext_live/faq.html>`__ for more information on the immediate changes (also described in some detail below). Build Changes from Client Library 1.x ##################################### * The Omniverse USD Resolver plugin is now separated from the Client Library, so it adds build dependencies to Connectors. * There is a very simple checkpoint API in the resolver plugin that Connectors will probably want to include, so adding the resolver as a build dependency is a new step. * The Client Library no longer depends on USD (this enables us to provide more USD versions in the future) * The Connect Sample has a build script that "double fetches" using the Packman dependency system. * First it grabs the correct Omniverse USD Resolver plugin which contains the USD library dependency and the Client Library dependency locations * These are then fetched and land here: * _build/target-deps/omni_usd_resolver * _build/target-deps/usd * _build/target-deps/omni_client_library Initialization Changes ###################### * Because the USD Resolver plugin is no longer bundled with the Client Library it needs to be either copied to the correct folder for your application or initialized wherever you decide to use it. * The Connect Samples copy the USD Resolver files into the correct place so it is automatically initialized, but we made an example for initializing the resolver plugin anyway in ``liveSession.cpp``. For more information on explicitly initializing the plugin, see the `resolver docs in the "Initializing" section `_. API Changes ########### * All of the different ``OmniClient*.h`` files with interfaces required by a client are now combined into a single ``OmniClient.h`` file. * The application no longer has a "live mode" controllable by the client library API. If a developer is editing a layer with a ``.live`` file extension and uses ``omniClientLiveProcess()`` then all changes are automatically sent and received. * The resolver can now be used to set a checkpoint message because every file save generates checkpoints (labeled or not): ``omniUsdResolverSetCheckpointMessage()`` Live Changes ############ Client and Resolver Changes ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * The live transfer of data between clients and Omniverse servers has been revamped with these goals in mind: * Support the full USD feature set. Anything that can be done in USD is supported with live layers. * Multiple simultaneous editors. This includes being able to edit the same prims, and even the same attributes, at the exact same time. * High performance. The power of live layers comes from their interactive speeds. However, performance must not come at the cost of correctness. * Read more about the intricacies in the `USD Resolver technical overview documentation `_ * Only .live files/layers resident on an Omniverse server will replicate data * ``omniClientLiveProcess()`` is used to both send and receive changes to and from the Omniverse server. It is no longer required to save the .live layer using the USD Save API. Live Session implications - Non-Destructive Live Session Workflow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To go along with only replicating data through .live layers the Omniverse team is formalizing a scheme for Omniverse applications and Connectors to have robust live editing sessions. The idea is that when a Connector or content creation tool generates USD data (stages, props, etc), we want creators to be able to live-collaborate without unintentionally destroying or modifying that data. * Live stage composition * The .live layer is inserted, by each participating client, into the Session Layer. This is done for two reasons: * This avoids altering the original USD stage * All changes made in the .live layer will take authority over data in the base, or root USD stage. * Example:: Live_Stage.usd -------------- Session Layer |_ root.live (layer) |_ (overs replicated by Omniverse) Root Layer |_ /World |_ (Prims with overs in root.live) * Live stage file and folder structure * The .live layer files need to live somewhere on the Omniverse server so we established a common location for them. * .live folder - All live session files are stored in a folder called ".live" * ``usd_root_stage.live`` folder - a folder is created for each root USD file since a live session can only apply to one particular USD file * ``session_name.live`` - each session gets it's own folder to store the session files * Session files - there are three files that exist for each session * ``root.live`` - the .live layer where overs and new defs are stored for the session * ``__session__.channel`` - the channel file used by clients to send and receive Omniverse channel messages with other clients (peer presence, merge intentions, etc.) * ``__session__.toml`` - a configuration file for the live session * Inside the same folder where the USD root file ``usd_root_stage.usd`` being live-edited in a session called ``session_name``, a folder structure like this would exist: * ``./.live/usd_root_stage.live/session_name.live/...`` * Live session configuration file: ``__session__.toml`` * It contains these key/value pairs:: * version = "1.0" * user_name = "owner_user_name" * mode = "default" ("auto_authoring", "root_authoring", "project_authoring") * stage_url = "omniverse://server/path/root_stage.usd" * (optional) description = "A description of the session purpose" * When a client creates a new session, this file should be created with the above key/value pairs defined. The ``user_name`` value should be the owner's username for the URL defined in ``stage_url``. * Live session channel communication * An Omniverse Channel is used to communicate peer presence and merge status in the live session between clients. .. list-table:: Omniverse Channel JSON Format :widths: 15 15 10 60 :header-rows: 1 * - Key - Value - Type - Comments * - version - 3.0 - String - Message version. 3.0 is the version defined by Kit in this release. The version is composed as pattern [major].[minor]. If the major version is upgraded it is no longer backwards compatible. An increase of minor versions will still be backwards compatible and possibly add new keys. It's recommended that clients with old major versions cannot join sessions with a newer major version. * - from_user_name - Any String - String - User name. Since the Omniverse channel message only includes the user *ID* this field helps to provide a user-friendly login name. * - app - Any String - String - The application name of the connected client (*Create*, *View*, *C++ Connect Sample*, *Maya*, etc.). * - message_type - * ``JOIN`` * ``GET_USERS`` * ``HELLO`` * ``LEFT`` * ``MESSAGE`` - String - The message type. It supports these messages types: * ``JOIN`` - Sent when a new user is joins. Nucleus channel will send out the join message after the user is firstly connected to the channel, however, it only includes the user id but not the readable user name. We extend it with a customized message. So connectors should send out this when it’s joined into a session. * ``HELLO`` - The response to ``JOIN`` or ``GET_USERS`` messages, as Nucleus channel is stateless, so any new users that join into the channel do not know who are in that channel already. So connectors should send out this when it receives any ``JOIN`` message. * ``GET_USERS`` - When a client receives a GET_USERS message, it should respond to a HELLO message. Instead of JOIN, GET_USERS means the client wants to know other clients in the session but has not joined in this session yet. Clients receiving GET_USERS messages are recommended not to treat this client as a joined user in this session. * ``LEFT`` - Sent when the user quits the live session. * ``MESSAGE`` - Customized message based on the application. Application can design the protocol with a content field and parse the content field for details. * - content - Any dict - Dict - A dictionary that includes all customized protocols based on the application * Here are examples in JSON format based on the message specification:: {"version": "3.0", "from_user_name": "omniverse", "message_type": "JOIN", "content": {}} {"version": "3.0", "from_user_name": "omniverse", "message_type": "LEFT", "content": {}} {"version": "3.0", "from_user_name": "omniverse", "message_type": "HELLO", "content": {}} * Customized Messages for Managing the Session Merge Process * At the end of a live session the session owner my merge live changes into the base layers. In order for other users to be notified, the following messages are specified: * NOTE: The following specification is based on the session management protocol in the last section. And it's defined when the ``message_type = MESSAGE``. And the contents are contained in the payload of the ``content`` field. The data type is a Dict that's keyed for different purposes. * The content of the Dict includes a pair of items that has a group key for marking different groups of usages. For session management, the key is ``__SESSION_MANAGEMENT__``. And the value is another dict to describe the details: .. list-table:: Merge Session Message JSON Format :widths: 15 15 10 60 :header-rows: 1 * - Key - Value - Type - Comments * - version - 1.0 - String - Message version. 1.0 is the version defined the current live session protocol. * - message - * ``MERGE_STARTED`` * ``MERGE_FINISHED`` - String - * ``MERGE_STARTED`` - Sent when the owner starts to merge the live changes (possibly by opening the merge dialog). When a client receives this message it should disable any further changes to the .live layer and pop up a modal dialog indicating this. * ``MERGE_FINISHED`` - Sent when the merge is complete * An example of a ``MERGE_STARTED`` message sent in JSON is like:: { "version": "3.0", "from_user_name": "omniverse", "message_type": "MESSAGE", "content": {"__SESSION_MANAGEMENT__" : {"version": "1.0", "message": "MERGE_STARTED"}} } * Disabling and Deleting Prims * USD prims that are defined in the root layer cannot be deleted with an "over", it's not possible. If the client intends to delete a prim from the root layer it must use `UsdPrim::SetActive(false) `_ to deactivate the prim. This will effectively remove the prim from the viewport by setting its "active" metadata to false. This doesn't remove the prim or any of its children from the stage file, but default stage traversals will no longer see it. `This USD glossary entry for Active/Inactive `_ discusses "non destructive and reversible prim deletion". * Merging live session changes * When a session is complete and the owner wants to keep the changes from the session, they can choose to merge them into the root stage. * ``default``, or ``root_authoring`` mode: in this case, the .live and root layers are flattened in a temporary stage, then copied into the stage's root layer. * ``auto_authoring`` mode: each live layer is merged into its respective root sublayer (currently this is experimental and only Create can support such a session) * See the `Live Workflow Glossary `_ for more information about these modes. * The specific "merge and end session" process works like this: #. Verify that the current connected user is actually the "owner" of the session #. Send a ``MERGE_STARTED`` channel message #. At this point other clients will disconnect from the live session to prevent any unwanted changes #. Create a non-forced checkpoint on the live layer #. Create a non-forced checkpoint on the root layer #. Merge the live changes to the root layer #. Create a checkpoint on the root layer while saving it #. Clear the live layer changes #. Remove the .live layer from the session layer (so that the open stage is still valid for editing in the client) #. Send a ``MERGE_FINISHED`` channel message .live Layers Without Sessions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some clients may choose to forgo the Live Session workflow and simply use .live sublayers in their layer composition. A .live layer acts just like USD to the client, so when the client sets the edit target to ``Original_Stage_Edits.live`` all changes will be replicated through Nucleus. This is assuming that ``omniClientLiveProcess()`` is being called on all clients (Create automatically does this). This doesn't require a "live session" to be active. Note, the HelloWorld sample still allows you to open a .live file and edit it, demonstrating this point. Example:: Original_Stage.usd -------------- |_ Original_Stage_Edits.live (layer) |_ (overs replicated by Omniverse) |_ Original_Stage_Base.usd (layer) |_ /World |_ (Prims with overs in Original_Stage_Edits.live) Multiple USD versions ##################### Because the Client Library no longer depends on USD we plan to distribute multiple versions of the Connect Sample for different USD versions. The specific list is to be determined, but the Omniverse team is expanding its capabilities to rapidly generate builds for distribution to customers with different dependency requirements: * Python * Boost * TBB * USD version * etc. Client and Resolver Documentation ################################# * `Omniverse USD Resolver `_ * `Omniverse Client Library `_ Locating the Samples source from the Launcher --------------------------------------------- To find where the Connect Sample is installed, find the Connect Sample under the Library:Connectors tab, click the hamburger icon and select "Settings": .. image:: /content/images/connect_sample_launcher_hamburger.png :align: center :alt: Go to the Settings from the hamburger menu button :width: 640px | Clicking the folder icon next to the Install Path will open a file browser window to where it is installed: .. image:: /content/images/connect_sample_launcher_folder.png :align: center :alt: Click the folder icon to open the install location of the Connect Sample :width: 320px Configuring MSVC (Advanced) --------------------------- When ``build.bat`` is executed (or if ``repo.bat build``) a version of the Microsoft Visual Studio Compiler and the Windows 10/11 SDK are downloaded and referenced by the generated Visual Studio projects. If a user wants the projects to use an installed version of Visual Studio then simply run ``build.bat --use-devenv``. This will use ``vswhere.exe`` to discover where Visual Studio is installed and will build using ``devenv`` rather than ``MSBuild``. Creating a Windows USD App from the Omniverse Connect Sample ------------------------------------------------------------ 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. Dependencies for Omniverse Client Library and USD ################################################# Both the Omniverse Client Library and NVIDIA's modified USD SDK 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 using either ``prebuild.bat`` or ``build.bat``): * ``_build\target-deps\usd`` * ``_build\target-deps\omni_client_library`` * ``_build\target-deps\omni_usd_resolver`` These dependencies contain symbolic links, so care must be taken when copying them into the simple app's folders. `robocopy `__ (distributed with Windows 10/11) does a good job of deep-copying symbolic links. The ``deps`` folder will hold the USD and Client Library dependencies for the application. Here are a couple command lines that can be run from within the Connect Sample's root folder, note that in this case the simple project is located in the ``X:\tmp\OmniUSDReader`` directory: * ``robocopy /S _build\target-deps\usd X:\tmp\OmniUSDReader\deps\usd`` * ``robocopy /S _build\target-deps\omni_client_library X:\tmp\OmniUSDReader\deps\omni_client_library`` * ``robocopy /S _build\target-deps\omni_usd_resolver X:\tmp\OmniUSDReader\deps\omni_usd_resolver`` Project Settings ################ 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 ^^^^^^^^^^^^^^^ .. image:: /content/images/connect_sample_example_linker_options.png :align: center :alt: Visual Studio Linker Options :width: 640px 1. Additional Library Directories: * Debug * ``deps\nv_usd\debug\lib;deps\omni_client_library\debug`` * Release * ``deps\nv_usd\release\lib;deps\omni_client_library\release`` 2. Additional Dependencies: * Debug * .. code-block:: ar.lib;arch.lib;gf.lib;js.lib;kind.lib;pcp.lib;plug.lib;sdf.lib;tf.lib;trace.lib;usd.lib;usdGeom.lib;vt.lib;work.lib;usdShade.lib;usdLux.lib;omniclient.lib;python37.lib;boost_python37-vc141-mt-gd-x64-1_68.lib * Release * .. code-block:: ar.lib;arch.lib;gf.lib;js.lib;kind.lib;pcp.lib;plug.lib;sdf.lib;tf.lib;trace.lib;usd.lib;usdGeom.lib;vt.lib;work.lib;usdShade.lib;usdLux.lib;omniclient.lib;python37.lib;boost_python37-vc141-mt-x64-1_68.lib * Note that the boost python library is the only difference between debug and release C/C++ Compiler Settings ^^^^^^^^^^^^^^^^^^^^^^^ .. image:: /content/images/connect_sample_example_compiler_options.png :align: center :alt: Visual Studio C++ Options :width: 640px 3. Additional Options (to silence warnings): * ``/wd4244 /wd4305`` 4. Additional Include Directories: * Debug * ``deps\usd\debug\include;deps\omni_client_library\include;deps\omni_usd_resolver\include`` * Release * ``deps\usd\release\include;deps\omni_client_library\include;deps\omni_usd_resolver\include`` 5. Preprocessor Definitions: * Debug * ``BOOST_ALL_DYN_LINK;NOMINMAX;TBB_USE_DEBUG=1`` * Release * ``BOOST_ALL_DYN_LINK;NOMINMAX;TBB_USE_DEBUG=0`` 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. .. image:: /content/images/connect_sample_example_post_build_event.png :align: center :alt: Visual Studio C++ Options :width: 640px 6. 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``. 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`` Release Notes ------------- 202.0 Point Release ################### * Samples * Update the repo build tools to modern versions (OM-77486) * Add a test script for all programs ("repo test" or tests/test_all.[bat,sh]) * Allow Windows users to use their installed build tools with "repo build --use-devenv" (OM-74840) * Change defaultPrim handling to be less hardcoded and more correct * Add a function to determine if any prims exist in the root layer before merging (OM-64707) * Add a note in README.md about Visual Studio failing to iterate on builds (OM-78756) * Add a prop payload and reference to a HelloWorld (OM-35218) * Modify an OmniPBR MDL parameter for a referenced prop * Set the defaultPrim to kind=assembly, all others to kind=component * Correctly set the USD Preview Surface bias, scale, and sourceColorSpace * Correctly apply the MaterialBindingAPI to the box mesh prim * Change OmniCLI to overwrite destination folders for copy and move (OM-80541) * Omniverse USD Resolver * `1.20.0 Changes `_ * Omniverse Client Library * `2.23.0 Changes `_ * Omniverse Asset Validator * `0.2.2 Changes `_ 201.0 Point Release ################### * Samples * Added omni_asset_validator.bat|sh which uses the `Asset Validator `_ to find issues in USD layer file URIs * Added 'v' validate option for pyLiveSession to demonstrate the Asset Validator on an in-memory stage. * Create extents attributes on all meshes in HelloWorld (so we don't fail the asset validation checks) * Add example usage of TfMakeValidIdentifier() so prim names are valid (OM-66072) * Modify the build config and source to support 2022-era USD versions (OM-53579) * Don't throw an exception when the user name is not valid in the Python sample * Update msvc to 2019-16.11.17-ndebug (14.29.30133) to no longer release debug CRT (OM-42026) * Prevent "Core::unregister callback called after shutdown" in samples by clearing the client log callback * Report the update frequency and run duration in the simple sensor example * Support reusing the live stage in the simple sensor example rather than deleting it every run * Make the Materials parent prim a Scope * Make Fieldstone.mdl use the OmniPBR.mdl that ships with the sample (OM-73976) * Omniverse USD Resolver * `1.18.0 Changes `_ * Omniverse Client Library * `2.21.0 Changes `_ * Omniverse Asset Validator * `0.2.1 Changes `_ 200.1 Update ############## This small update to the Connect Samples fixes some simple bugs in the live session classes and updates the Omniverse Client Library and USD Resolver with the latest versions. * Samples * Fix the “MESSAGE” message type and custom “message” key to be case correct * Ensure that we flush live layer clears with omniClientLiveProcess() * Clear the peer users in LeaveChannel() allows for recycling the class * Fix the usd_resolver post build copy step in UsdReader example * Omniverse USD Resolver * `1.11.0 Changes `_ * Omniverse Client Library * `2.15.0 Changes `_ 200.0 Point Release ################### The 200.0 release signifies big changes with the distributed Omniverse libraries. The Omniverse team has separated the USD resolver plugin from the Client library to make it easier to support more versions of USD. Live synchronization is improved for the purposes of performance, simultaneous editors, and supporting the entire USD layer editing feature set. Omniverse applications and Connectors are also now subscribing to the notion of live sessions to support non-destructive workflows. This version of the Connect Samples includes new Python and C++ examples to demonstrate this live session workflow. * Samples * Added the LiveSession examples along with an introductory LiveSession Library that contains many required components to support the new live session workflow * Omniverse USD Resolver * `1.9.0 `_ * Omniverse Client Library * `2.13.0 `_ 104.1 Point Release ################### * Samples * Added physics to HelloWorld sample to showcase UsdPhysics usage. .. image:: /content/images/connect_sample_drop_cube_on_plane.gif :align: center :alt: Press play to see physics working in the sample :width: 640px * Added the file hash to the stat output in OmniCLI * Added "cver" command to print client version * Change the live rotations from ZYX to XYZ and all xform ops to double3 * Omniverse Client Library * 1.17.4 * OM-47554: Downgrade some "Error" messages during auth to "Verbose" * We attempt to connect using 3 different methods, and it's normal for 2 of them to fail. This avoids confusing users with error messages for a connection that ultimately succeeds. * OM-48252: Lower required "list2" version, to allow connecting to servers running Nucleus 112.0. * 1.17.3 * CC-357: Fixed a deadlock that could occur when a python file status callback is being unregistered on one thread while another thread is simultaneously trying to call that file status callback * CC-367: Allow stat & list using cloudfront.net URLs * OM-45178: Print extended error message when Token.subscribe fails * OM-45887: Enable extra connection logging * CC-384: Remove support for Nucleus 107, 109, and 110 * CC-366: Update OpenSSL to avoid a security vulnerability * 1.17.2 * CC-32: Fixed a crash that could happen on disconnect * OM-43009: Removed "stop" from list of required capabilities, to discover newer servers which don't advertise that capability * CC-236: Add support for checkpoint change notification * CC-245: Fixed a deadlock that could occur rarely when connection failed. * 1.17.1 * CC-228: subscription based authentication using 'nonce' * CC-231: Discover API server using minimum required capabilities rather than all capabilites * CC-229: Fixed a case where the client library would not connect to Nucleus securely * 1.17.0 * CC-7: Add shutdown guard to omniclient::Core * 1.16.0 * OM-39826: Prevent copying of channels from nucleus servers to other providers * OM-38687: Fix crash when shutdown with an outstanding stat subscription * OM-37095: Use omniClientWait in blocking python binding functions * OM-38761: Fix ResolveSubscribe to handle more invalid search paths * OM-39746: Support stat('/') on S3 buckets. S3 API does not support stat() on root, but we can fill in the gaps * 1.15.0 * OM-39614: Fixed a case where pings would not report a connection error * OM-36524: update connection library to prevent using Nucleus Cache when accessing localhost servers * OM-37061: Fix crash if a request is started after it is stopped * OM-34916: Map MountExistsUnderPath error to ErrorNotSupported * OM-38761: Fixed StatImpl::beginWatch to always call the provided callback, even when the uri to watch is invalid. * OM-39367: Removed "fast locked updates" because it's fundamentally broken. Removes omniUsdLiveLock & omniUsdLiveUnlock * OM-23042: If the relativePath starts with "./" then don't use search paths * 1.14.0 * OM-38721: Added function omniClientGetLocalFile which returns the local filename for a URL * If the input URL is already a local file, it is returned without error * If the remote file has not yet been downloaded to cache, it is downloaded before returning * Python bindings are "get_local_file" "get_local_file_async" and "get_local_file_with_callback" * OM-38816: Added environment variable OMNI_DEPLOYMENT which can override the deployment sent to discovery * OM-37061: Early exit from callback if cacheEntry weak_ptr is expired, correct creation of cacheEntry ownership * 1.13.25 * OM-34145: Fix omniClientCopy to not infinitely copy when copying a directory into a subdirectory of itself. * 1.13.24 * OM-38028: Update Brotli, OpenSSL, and libcurl versions * 1.13.23 * OM-37701: Fix FetchToLocalResolvedPath to work with SdfFileFormat arguments * 1.13.22 * OM-37276: Use latest idl.cpp to pickup SSL cert directory location fixes * 1.13.21 * OM-36064 & OM-36306: Fix crash in listSubscribe on disconnect * 1.13.20 * OM-37054: Fix incorrect search order according to PBR specification * OM-36511: Add python bindings set_authentication_message_box_callback & authentication_cancel 103.1 Point Release ################### * Samples * Added omniUsdReader, a very simple program for build config demonstration that opens a stage and traverses it, printing all of the prims * Added omniUsdaWatcher, a live USD watcher that outputs a constantly updating USDA file on disk * Updated the nv-usd library to one with symbols so the Visual Studio Debug Visualizers work properly * Omniverse Client Library * Still using 1.13.19 102.1 Point Release ################### * Samples * OM-31648: Add a windows build tool configuration utility if the user wants to use an installed MSVC and the Windows SDK * Add a dome light with texture to the stage * OM-35991: Modify the MDL names and paths to reduce some code redundancy based on a forum post * Add Nucleus checkpoints to the Python sample * Avoid writing Nucleus checkpoints when live mode is enabled, this isn't supported properly * OM-37005: Fix a bug in the Python sample batch file if the sample was installed in a path with spaces * Make the /Root prim the `defaultPrim` * Update Omniverse Client Library to 1.13.19 * Omniverse Client Library * 1.13.19 * OM-36925: Fix omniClientMakeRelative("omni://host/path/", "omni://host/path/"); * 1.13.18 * OM-25931: Fixed some issues around changing and calling the log callback to reduce hangs. * OM-36755: Fixed possible use-after-delete issue with set_log_callback (Python). * 1.13.17 * OM-34879: Hard-code "mdl" as "not a layer" to work around a problem that happens if the "usdMdl" plugin is loaded * 1.13.16 * OM-36756: Fix crash that could happen if two threads read a layer at the exact same time. * 1.13.15 * OM-35235: Fix various hangs by changing all bindings to release the GIL except in very specific cases. * 1.13.14 * OM-34879: Fix hang in some circumstances by delaying USD plugin registration until later * OM-33732: Remove USD diagnostic delegate * 1.13.13 * OM-36256: Fixed S3 provider from generating a bad AWS signature when Omni Cache is enabled * 1.13.12 * OM-20572: Fixed setAcls * 1.13.11 * OM-35397: Fixed a bug that caused Linux's File Watcher Thread to peg the CPU in some cases. * 1.13.10 * OM-32244: Fixed a very rare crash that could occur when reading a local file that another process has locked * 1.13.9 * OM-35050: Fixed problem reloading a non-live layer after it's been modified. * 1.13.8 * OM-34739: Fix regression loading MDLs introduced in * 1.13.3 * OM-33949: makeRelativeUrl prepends "./" to relative paths * OM-34752: Make sure local paths are always using "" inside USD on Windows * 1.13.7 * OM-34696: Fixed bug when S3 + cloudfront + omni cache are all used * 1.13.6 * OM-33914: Fixed crash when accessing http provider from multiple threads simultaneously * 1.13.5 * OM-26039: Fixed "Restoring checkpoint while USD stage is opened live wipes the content" * OM-33753: Fixed "running massive amounts of live edits together causes massive amounts of checkpoints" * OM-34432: Fixed "[Create] It will lose all data or hang Create in live session" * These were all the same underlying issue: When a layer is overwritten in live mode it was cleared and set as 'dirty' which would cause the next "Save()" (which happens every frame in live mode) to save the cleared layer back to the Omniverse server. * 1.13.4 * OM-31830: omniClientCopy() with HTTP/S3 provider as source * OM-33321: Use Omni Cache 2.4.1+ new reverse proxy feature for HTTPS caching * 1.13.3 * OM-33483: Don't crash when trying to save a layer that came from a mount * OM-27233: Support loading non-USD files (abc, drc, etc) * OM-4613 & OM-34150: Support saving usda files as ascii * Note this change means live updates no longer work with usda files (though they technically never did -- it would silently convert them to usdc files). 101.1 Point Release ################### * Add Linux package for the Omniverse Launcher * Add a Python 3 Hello World sample * Update the Omniverse Client Library to 1.13 * Update to Python 3.7 * Add a Nucleus Checkpoint example * Add the ability to create/access a USD stage on local disk in the Hello World sample 100.2 Update ############ * Update the Omniverse Client Library fix an issue with overlapping file writes 100.1 Point Release ################### * First release * HelloWorld sample that demonstrates how to: * connect to an Omniverse server * create a USD stage * create a polygonal box and add it to the stage * upload an MDL material and its textures to an Omniverse server * bind an MDL and USD Preview Surface material to the box * add a light to the stage * move and rotate the box with live updates * print verbose Omniverse logs * open an existing stage and find a mesh to do live edits * OmniCLI sample that exercises most of the Omniverse Client Library API