AYON and USD

Hey everyone.

Let me summarize in this topic current state of USD in AYON and our future plans so we can open discussion.

Intro

USD is a well-known and complex tool in this community. Understanding its concepts and incorporating them into a studio pipeline can be challenging. However, there have been recent developments that aim to bring some standardization to USD. The Alliance for OpenUSD (AOUSD), a non-profit organization, has taken USD under its umbrella, which is expected to contribute to its evolution.

USD encompasses various concepts such as sub-layers, reference composition arcs, variant sets, and shading schemas. It also offers integration with renderers through Hydra and interoperability between DCCs with MaterialX. Furthermore, there are other exciting developments on the horizon. It’s important to note that certain aspects of USD are implementation-specific, such as choosing between low-level or high-level USD API and determining the composition approach based on production requirements. These decisions cannot be universally defined by a one-size-fits-all pipeline.

From AYON’s perspective, it is crucial to embrace the Asset Management aspect of the USD workflow. This involves providing an AYON connected Asset Resolver (AR) and basic tools for managing composition, publishing, and loading USD layers. Integrating tools like usdview can offer visual feedback and aid in scene debugging. However, AYON should not impose strict guidelines on how USD should be used in specific scenes, such as dictating the node graph structure in Houdini or specifying the placement of LOP nodes and Python nodes. Instead, the focus should be on what can be effectively achieved. There are already existing USD-related pieces in AYON, like those developed by @BigRoy for Houdini, which can serve as a foundation for additional work and provide inspiration. Maya has Multiverse support but a robust, native AYON solution is still needed.

The work on it can be divided into multiple topics:

Asset Resolution (AR)

The heart of working with USD assets in USD is the Asset Resolver. It is a plugin that implements the ArResolver interface of the USD API to handle asset paths defined within USD. Implementing an Asset Resolver can be challenging due to performance issues. Additionally, USD does not support custom resolvers implemented in Python, again because of performance and multi-threaded systems.

We have implemented a prototype USD Asset Resolver that works with AYON API to resolve paths. This means you no longer need to statically build the USD hierarchy; instead, you can use URIs like:

ayon+entity://super_cool_project/MegaAsset?product=model&version=v005&representation=usd

That will be resolved on the fly to a specific path pointing to storage based on the current platform. This means that when you are on-site on a Windows machine, the resolved path will be something like:

P:\SuperCoolProject\Assets\MegaAsset\publish\model\v005\MegaAsset_model_v005.usd

but on linux it will end up like

/mnt/studio/projects/SuperCoolProject/Assets/MegaAsset/publish/model/v005/MegaAsset_model_v005.usd

You get the idea. Anyway, this prototype is still a work in progress as it needs performance optimizations like proper caching - but also adding support for selectors to be more flexible with the URIs.

Instead of using &version=v005, we can use something like &version=latest or &version=approved, or even some time/date selectors, etc.

Another concern is the need for adequate render farm support. When submitting a task to the farm, it is undesirable for all nodes to execute the Asset Resolver and repeatedly query the server. Instead, at this stage, all paths should be “baked” and retrieved from a sidecar cache file, which will be managed by the Asset Resolver code.

We also offer support for OpenAssetIO, which handles similar tasks. OpenAssetIO provides its own Asset Resolver that can be used as an alternative or supplement to the AYON Asset Resolver. It is possible to register multiple asset resolver plugins.

Folder structure for USD

USD can describe many things, from a single asset to complex shots, and is usually composed of additional files nested in some form of hierarchy. To support this, along with “traditional” workflows, we need to define some default templating of the USD hierarchy. Some of it can be helped by the use of symlinks, but that itself poses some difficulties on different platforms and storage systems. Assets can be nested or in a flat hierarchy, and so on. One of the proposals is to have a structure like:

Project / Asset Hierarchy Folders / Asset /work (for workfiles) /publish (for published data) / {family} / {variant} / {version} / [files] /stage (for USD stage) / {usd_families} / {variant} / {version} / [usd files] /sub_assets / {asset} / {stage} / {usd_families} / {variant} / [usd files] /sub_assets …

USD families should reflect existing families in AYON (or add necessary new ones) like stage, model, animation, texture, material and so on.

Tools

:warning: this section is still WIP, mostly quick ideas thrown here for disussion

USD Context Builder

We will need to add something like workfile builder but for USD - mainly for shot-based USD file to automatically create hierarchy and related USD files based on what is already published.

USD Version Control

That would be UI tool to easily manage versions inside the whole USD hierarchy - to easily switch versions, or freeze them for some packaging or farm rendering perhaps.

Sublayer Tool

This is maybe the same thing as USD Version Control tool with additional features. It should manage versions of sublayers, re-ordering and adding published layers from different contexts, live view of the data, etc.

There might be need for other host specific tools but I think there is pretty much solid toolset already in Maya and Houdini that we shouldn’t try to replace. Only add functions that are specific to AYON workflows or are in some way missing.

USD Addon

USD support should be bundled as an AYON addon that will contain built-in USD tools like usdview, etc. These tools can then be used within other USD applications to preview USD files, for debugging, etc. This might be a little challenging because we need to support Windows, Linux (multiple distributions), and macOS (multiple versions of the OS and perhaps Intel/M1/M2 variants too?). We’ll need to create some infrastructure and scripts around it - at least for the Asset Resolver, as it needs to be built against individual USD framework versions used by DCCs.


Note that this list is really just a quick draft, but since there was some interest expressed over Discord channels about it, I think we need to kick off some public discussion here where it is more persistent. Feel free to comment on it in any way, and I’ll try to maintain this topic as USD support in AYON takes a more definitive shape.

6 Likes

Is local disk mapping considered for the Asset Resolver as well?
For example of a remote artist is using drive Y instead of X.

Is there danger of a mighty long path to a file with this hierarchy?

Could this be considered the next iteration of the templated workfiles?

AYON is actually taking into account local site-id and platform so it is treating paths the same way as in DCC - ie. translating root-less path to its local platform specific path

There definitely is and it is up to the studio if they want to go this way. If you are purely linux based, there is no real danger. On Windows, that 260 limit might still apply, but that is based on application running on Windows, not on Windows as OS (as it provides API without this limit). Unfortunately I think Maya is still using the “old” API.

Yes, exactly. I think this tool would be at the end the most crucial tool to work with USD in AYON so great love needs to be put there :slight_smile:

The Asset Resolver needs to be coded in C++, so IINM it needs to be compiled for every version of USD used in the pipeline. That means we need a binary of the AR for Houdini, another for Maya, another for Nuke and another for Katana. Every time we want to move to a new version of a DCC, we need a new binary of the AR plugin. That plugin will need to be very easily compiled for every pipeline TD to do it themselves and without too much knowledge required.

I was wondreing if it would be better for AYON to provide their own AR, or to provide one through OpenAssetIO. If we could use the same URIs everywhere (in USD, in Maya, in Houdini) for AYON through the use of OpenAssetIO, it would be fantastic and a big selling point for AYON in my opinion.

It might be obvious to some, but I know it was not to everybody at my last gig. The dynamic URIs can contain &version=latest, but latest here should really mean latestValid. You don’t want to resolve latest to a version that has been marked as invalid or deleted. This means every status needs a valid not not attribute.

Another solution to the farm problem where you don’t want the URIs to be dynamic, is to add a timestamp in them. This way, you can say &version=latest&timestamp=2023-09-05T12:23:14 to get the latest version as it was on this day at this time. The system needs to garantee that things don’t change after that. I have no idea if the AYON db supports such mecanism.

In our current USD pipeline, we use a file structure where published usdc files (geometry, lookdev, anim bakes, etc.) are inside a folder structure similar to the one you described, and then we have the layerStack files (the one file to load for an asset or a shot, containing the layers which reference the published files) in their own Family. This can vary wildly from studio to studio an I don’t think the AOUSD will standardize this any time soon.

F

Currently those URIs are used in both AYON AR and OpenAssetIO manager and they are in a form mentioned above:

ayon+entity://{project}/{asset}?product={product}&version={version}&representation={representation}

We lack support for various version selectors yet and I completely agree with the difference between “latest” and “latest valid” - you might even add criteria like “latest approved”. But with this URI used in USD, you might be able to switch between AYON AR and OpenAssetIO resolver seamlessly and that maybe later on, when both are more adapted, more variants of AR based on them will be available to choose from.

We aim for immutable versions even though there are ways to configure pipeline to be able to overwrite them so timestamp and even time range selector (like “approved version between these timestamps”) would definitely help.

True and also one of the large obstacles because we try to support such a wide range of DCCs, their versions and platform. But with AR we might be more strict and perhaps support only selection of them.

1 Like

Are there any lightweight python facing functions to constructing the AYON urls and decomposing them back?

Is it something like this to format it?

# product = subset
url = "ayon+entity://{project}/{asset}?product={product}&version={version}&representation={representation}"

And how would I parse such an URL?

This is still work in process - currently implemented (and working) is AYON OpenAssetIO Manager plugin.

 ref_string = (
     f"ayon+entity://{entity_info.project_name}/"
     f"{entity_info.path}?"
     f"product={entity_info.product_name}&"
     f"version={entity_info.version_name}&"
     f"representation={entity_info.representation_name}"
)

This will need some Python API around and also we’ll need to implement some more “selectors” to the end-point. Currently this is now working in similar fashions as USD resolver.

You need to provide x-ayon-site-id header so AYON server can get you the resolved path, but to get that ID, you can use:

f"http://ayon_server/api/system/sites?hostname={hostname}&platform={system_platform.lower()}"

As a side note (just because I’ve remembered yesterday) - Windows support long path prefix - you can write any path in this form

\\.\C:\Some\Hyper\LongPath

or

\\?\C:\Some Hyper\LongPath

or even

\\?\UNC\server\share\Some Hyper\LongPath

(difference between \\.\ and \\?\ is that variant with ? is not normalized (slashes to back-slashes))

More info here:

Would the idea be that any USD layers to be saved become a product of their own which then get joined into the final USD file? Or how do we feel USD files should should get managed in AYON itself?

Imagine a structure like this:

image

Or a slightly more involved example:

image

Note that here the shot’s animation caches for a character are sublayered in (purely to show they end up in the animation.usd file) but I’d assume those caches would instead get referenced onto the loaded assets instead of sublayered at the root of the animation.usd layer

In this example I’ve also used layout.usd as the step that others refer to as “build” or “manifest” where I’m referencing in the separate USD assets to be animated.


Side note:

Just wanted to add a note that the structure shown here is somewhat equivalent to Pixar’s (old?) USD End to End example and matches roughly the usdlib that is in OpenPype for Asset and Shot structure that it generates - even though I believe that’s highly unused and actually originates 1-to-1 from a USD test project we did a 3+ years ago and thus came from our code repository here.

Feels like we should keep everything as ‘pixary ’ as possible. I’m going to have to wrap my head around the nesting of these files. What having so many sub references brings. It’s almost like the hierarchy of the usd files is acting as the ‘ui’ for where change is allowed to slot in. Interesting. The files themselves can act as both the ui for what contributions can be expected for an asset… and even for the ‘inventory’ of what a shot expects to have.

Regarding the Asset Resolver and optimizing it I expect it might be useful getting wordy in this USD topic on Asset Resolver 2.0 and batching requests. Not sure who’s most knowledgeable with the Ayon Asset Resolver but I assume this might be of interest as discussion to be a part of.

1 Like

We’re actually talking to Tom and the rest of the team from OpenAssetIO a lot and often.

It is totally in the cards, to do the resolver once, properly with collabortaion and support it in AYON via OpenAssetIO.

I have created a draft PR with OpenPype x USD workflow features: Feature: USD Workflow for Maya, Houdini and Blender by BigRoy ¡ Pull Request #5925 ¡ ynput/OpenPype ¡ GitHub

It doesn’t do asset resolving yet, it doesn’t provide custom USD edit tools but it does provide a testable workflow between Houdini, Maya and Blender to continue the discussion.

If there’s an additional application needed for inititial testing let me know.

For now, workflow, testing feedback and questions are more than welcome in the PR.

1 Like

It’s looking really good as PoC.

if you want real challenge give it a shot in Unreal.

Hmm - how trivial is it to get up and running with Unreal + OpenPype if you have say 0.1% experience with Unreal? Do I get into project structure / compiler hell rather quickly? :smiley:

My focus isn’t on Unreal for myself - so I might want to nudge someone else to test Unreal aspects of it.

Doesn’t Unreal integration also actually move the files into the project structure (and thus upon load) you should also start ‘moving’ any sublayers/referenced paths in the USD layers, etc. Or are they loaded from the published representations just fine?

Anyway, if you have someone (developer) available I’d be happy to work together to see where I can help aiding them with the Unreal workflow of this PR. Would definitely be great to include that with the feature, yes.

Added another demo video to the PR, check out the Houdini + Maya model variants + lookdev workflow testing demo in the description of the Feature: USD Workflow for Maya, Houdini and Blender PR

This little demo shows:

  1. Creating an asset with a few model variations from Maya
  2. Creating an Arnold lookdev from Maya using LookdevX + Arnold and exporting that as a lookMain variant for the asset
  3. Loading the asset in Houdini, rendering 1-to-1 the same as Maya and then tweaking the shader in Houdini
  4. And then a lot more ‘playing’/‘talking’ about what could be done with that.

Direct video also here:

https://github.com/ynput/OpenPype/assets/2439881/87162e88-489f-405b-9c77-c1cd565be205

1 Like

It should be as easy as installing Unreal via Epic Store, configuring it in the Settings as usual, and launching it on some task. If you have Visual Studio available, it will build the integration plugins, if not, you can just add it with Epic Store. Anyway, I can have a look on what can be done on Unreal side of things.

1 Like