Home

Awesome

Replace Resolver,

An asset path resolver plugin for USD.

It is following the ArDefaultResolver logic, such as relative paths resolution using an "anchor" paths (see USD API documentation for more info) and is adding a substring replacement system.

Purpose of the Substring Replacement System

Custom asset resolvers are used to translate any asset paths found in the layer stack of a USD stage. For example, such asset path can be a URI used to retrieve a specific version of the asset from a data base.

To avoid adding a dependency with a database API, a solution is access a DB (to retrieve information such as asset versions) before opening a USD file and store the information in the USD layer metadata or in a sidecare file.

The advantage are multiple:

Scenario

Given a stage with some prims referencing some assets as bellow:

#usda 1.0

def "foo_01" (
	prepend references = @assets/foo/v1/foo.usda@
)
{
}

def "bar_01" (
	prepend references = @assets/bar/v4/bar.usda@)
{
}

We want to load the stage with a version v2 of foo and a version v5 of bar without authoring USD arcs explicitly.

Different strategies can be used

Describing the assets paths to be replaced using the AddReplacePair method of the ReplaceResolverContext

Can be useful to quickly test a replace pair for a specific asset path.

Adantage: Allow to open a USD file without any "replace versions" information in its meta data or sidecar json file).

Inconvenient: Code for the stage loaders in the DCC plugins or usdview must implement such logic.

# Python script to be executed from `/myshow`
from pxr import Ar
from pxr import Usd
from rdo import ReplaceResolver

import os

# Add an anchor path in the initialization of the ReplaceResolverContext
# to find our assets since they are referenced using relative paths
context = ReplaceResolver.ReplaceResolverContext(
	[os.path.join( os.getcwd(), 'published')])

# To replace foo v1 by foo v2
context.AddReplacePair('assets/foo/v1/foo.usda', 'assets/foo/v2/foo.usda')
# To replace bar v4 by bar v5
context.AddReplacePair('assets/bar/v4/bar.usda', 'assets/bar/v5/bar.usda')

# Open the stage with our context
stage = Usd.Stage.Open('published/shots/a_v1.usda', context)

# assuming foo and bar prims have a string attribute "version" matching their file version
assert (stage.GetPrimAtPath('/foo_01').GetAttribute('version').Get() == "v2")
assert (stage.GetPrimAtPath('/bar_01').GetAttribute('version').Get() == "v5")

Adding replace information in the 'customLayerData' of the root layer

This is the recommanded way in production.

# Python script executed from `/myshow`
from pxr import Ar
from pxr import Usd
from pxr import Vt
from rdo import ReplaceResolver
from shutil import copyfile

import os

# Copy the shot 'a_v1' we want to override to 'a_v2'
# (alternatively we could just "Stage.CreateNew('a_v2.usda')" and sublayer 'a_v1.usda'
copyfile('published/shots/a_v1.usda', 'published/shots/a_v2.usda')

stage = Usd.Stage.Open('published/shots/a_v2.usda')
replaceFoo = ['assets/foo/v1/foo.usda', 'assets/foo/v2/foo.usda']
replacerBar = ['assets/bar/v4/bar.usda', 'assets/bar/v5/bar.usda']

# We need to use a Vt array to set the data properly from Python
# https://github.com/PixarAnimationStudios/USD/issues/813
vtStringArray = Vt.StringArray(replaceFoo + replacerBar)

# Add the replace data to the stage custom meta data
stage.SetMetadata('customLayerData', {ReplaceResolver.Tokens.replacePairs: vtStringArray})
stage.Save()

# Setup our anchor search path using the environmnet variable
os.environ['PXR_AR_DEFAULT_SEARCH_PATH'] = os.path.abspath('published')

# Open the new shot version and check the version attributes
stage = Usd.Stage.Open('published/shots/a_v2.usda')
assert (stage.GetPrimAtPath('/foo_01').GetAttribute('version').Get() == "v2")
assert (stage.GetPrimAtPath('/bar_01').GetAttribute('version').Get() == "v5")

Using a side car json

If a file called "replace.json" exists in the same directory than the Usd file with the following data, it will be used to replace substrings. This can be used to override a USD file including.

[
	['assets/foo/v1/foo.usda', 'assets/foo/v2/foo.usda'], 
	['assets/bar/v4/bar.usda', 'assets/bar/v5/bar.usda']
]

Debug code

Adding following tokens to TD_DEBUG will print ReplaceResolver information

export TF_TOKEN=REPLACERESOLVER_PATH