Retiming Layers or Stage

Is there a way to retime a USD layer or stage similar to how you would with editing software?

Sdf.LayerOffset is almost what I’m looking for, but the problem with this is it only takes constant values for offset and scale. I can’t have a frame mapping like frame 50 retimes to frame 100, frame 51 retimes to frame 102, etc. etc.

Then there’s ValueClips, but their intended purpose seems more for splitting up different caches in the scene into multiple files rather than just global time remapping.

I can’t tell if this feature is missing or I’m doing it wrong.

In our pipeline, we primarily use Value Clips for splitting up data into multiple files, but using a single layer as a single Clip so that you can dynamically retime it is a perfectly valid use of Value Clips - we really don’t want to dictate policy for core features. So, with the understanding that DCC support for working with Value Clips may be limited, and that there is some performance cost to using them, they are, nevertheless, the only USD feature currently available to you to allow that kind of retiming.

Thanks for the reply. After some testing, Value Clips seems to work in cases where all data is contained within the clip layer, but if that layer sublayers or references layers, it no longer seems to work. I was trying to retime an entire shot usd, but the value clips didn’t work because the shot usd sublayers in department layers, and those department layers reference cache layers.

How do you retime a shot working around this limitation? Do you have to store a linear and retimed usd file for each cache layer using value clips and create two separate sets of department and shot layers for linear and retimed?

Sorry, I can’t think of a really workable mechanism in USD to accomplish what you’re looking to do, given your data organization. If all of your animating data were stored directly in the department layers in the “root layerStack”, then you could “simply” add a number of “Clip Sets” on each shot’s root prim, one for each department layer, in the strongest layer of the layerStack. These clipsets could then be retimed (you’d still need to retime each one, but at least they are all on the same prim) to retime the whole shot.

Pixar (generally, though some departments have explored publishing animated assets) puts all of our timeSamples into shot sublayers, so this could work for us. But I think most studios do as you describe, caching by model and bringing animation into a shot by reference/payload. And with this organization you’d have alot more work to do and find clipsets all over the scene graph to adjust.

I’ve been trying to implement retiming for all our caches following the value clip method and have a question.
Suppose the unretimed shot has

    endTimeCode = 2045
    framesPerSecond = 48
    startTimeCode = 1995

Suppose the shot needs to be retimed with a curve. For each cache I create a clip layer along the line of this trex_retimed.usda file:

#usda 1.0
(
    endTimeCode = 1020
    framesPerSecond = 24
    startTimeCode = 1000
    subLayers = [
        @./trex_hair_retimed.topology.usd@
    ]
)

over "Char"
{
    over "trex2" (
        clips = {
            dictionary default = {
                double2[] active = [(1000, 0)]
                asset[] assetPaths = [@./trex_hair_clip.usd@]
                asset manifestAssetPath = @./trex_hair_retimed.manifest.usd@
                string primPath = "/Char/trex2"
                double2[] times = [(1000, 2000), (1001, 2001), (1002, 2002), (1003, 2003), (1004, 2004), (1005, 2005), (1006, 2006), (1007, 2007), (1008, 2008), (1009, 2009), (1010, 2010), (1011, 2011), (1012, 2012), (1013, 2013), (1014, 2014), (1015, 2015), (1016, 2016), (1017, 2017), (1018, 2018), (1019, 2019), (1020, 2020)]
            }
        }
    )
    {
    }
}

It’s not clear to me how the various frame ranges and fps are handled in the composition of the layers.

  • It seems trex_hair_clip.usd which is the actual cache, should not contain any frame range and fps metadata, or the retime will not work. Is that correct? Why?
  • Note trex_retimed.usda contains frame range and fps. If I open trex_retimed.usda by itself, the retiming works, but as soon as it is sublayered, it stops working. What layer, if any, is supposed to define the frame range and fps?
  1. The root layer of any stage (or its primary session layer, as a session override) is the only layer whose startTimeCode/endTimeCode are consulted by the Stage
  2. You probably don’t want/need to be authoring framesPerSecond . Instead, set timeCodesPerSecond (See this for possibly helpful doc)
  3. While having those pieces of metadata set in the clip layers can be useful if you want to view or consume the layers in another context, none of them are important when the layer is used as a Value Clip. The consuming ClipSet should set times appropriately so that samples are consumed at the desired frequency and sample times

Does that answer your questions, Sylia?

It does, thank you!

I am implementing a solution for retimed shots where every cached object in the scene contains 2 variants: retimed and unretimed. Each variant references either an “unretimed” file which simply sublayers the cache, or a “retimed” file which defines the clip.
This works also for characters that have more than one cache, for example, an Anim cache, a Hair cache, and a Cloth cache. As long as each “retimed” file defines a clip with a different name they all layer correctly.

In the interactive program of choice we supply a tool/method to toggle between unretimed and retimed that

  • Switches the variant of all objects in the scene to “retimed” or “unretimed”.
  • Sets the new frame range.
  • Sets the new fps.

This has been a bit laborious to put in place, but it seems to do the trick and doesn’t require extra caches, only extra files (manifest, topology, etc) and of course the evaluation overhead for clips.

My next step is to try it with Houdini generated caches that use VDBs.

Just wanted to note that, while DCC support may still be nascent, your “switch all variants” need could be very concisely handled with the use of an expression variable driving the variant selections, so that you only need to change one value in the root layer to switch all variantSets together.

Regarding VDB’s… asset-pathed attributes should also retime as expected, though since renderers must consume a single VDB cache per rendered frame, you may get some slight frame-to-frame dilations depending on the shape of your timing “curve” in the times clip metadata.