LucaScheller / VFX-UsdAssetResolver

Usd Asset Resolver Reference Implementations
https://lucascheller.github.io/VFX-UsdAssetResolver/
Apache License 2.0
108 stars 22 forks source link

Accessing the stage in Resolver #8

Closed dovanbel closed 9 months ago

dovanbel commented 9 months ago

Hi,

First of all, many many thanks for open-sourcing your asset resolver!

We are at the early stages of implementing USD in our pipeline and I have been testing your CachedResolver.

I installed it and got it working in Houdini. I'm now starting to customize the PythonExpose module for our needs. My question is, how do I access the stage object in the Initialize method of the ResolverContext class.

My current idea is: in the resolver's Initialize method, fetch the metadata stored on the stage (meaning the current in memory stage in Houdini). This is similar to what you are explaining in the documentation using the separate mapping.usda file, but instead of fetching the mappingPairs from that external file, I would prefer to fetch it from the current in memory stage.

Is that possible ? Perhaps it doesn't make any sense ? :-)

Regards

Donat Van Bellinghen www.nozon.com

LucaScheller commented 9 months ago

Hey, thanks for checking out the resolvers!

So the issue with that is, that then resolver context is created, it isn't aware of the stage yet. The resolver context first gets created and then gets passed to the Stage.Open method.

When exposing things to Python, nothing is keeping you from accessing the stage via globals or other means. So you could "hack" aound it.

Since LOP nodes create stages on the fly, Houdini doesn't call "stage.Open" on a on disk USD file directly, rather stages are created in memory and files are sublayered onto the active or root layer. That means we can't easily target the active stage, because it changes per node or even per node cook.

Even if it works, you'll likely have the problem of refreshing the context as well (as there is some caching going on). So a valid solution could be to just add a Python LOP node after a sublayer node and then spawn the pinning from stage metadata and refresh the context. That should probably work.

(This is all theory, I might be wrong, so feel free to play around and correct me:) )

Cheers, Luca

dovanbel commented 9 months ago

Thanks Luca,

Ok that's clear, I will continue playing with it.

Cheers, Donat

dovanbel commented 9 months ago

Hi Luca,

I did some further test on your CachedResolver and got it working in Houdini.

I made a simple 'glass' asset, then referenced it in another asset 'table'. I then reference the 'table' in another stage. Using a python lop node, I can manipulate the mappingPairs so that I can for example switch the glass asset that is inside the table asset from it's version 1 to it's version 02. This is all working as it should, nice !

I have a question however : How could I have two 'table' asset references, one with the 'glass' asset in v01, and the other table with glass v02 ? I suppose I could do that perhaps in Houdini, by adding a second python lop node, and manipulating the mappingPairs a second time. But I don't see how this could work on the farm. If I were to use a mappingPair usd sidecar file, I wouldn't be able to differentiate between the two tables, as they are composed together in the usd file.

Maybe this idea of mixing versions of assets (having some glass assets resolving to the v01 and some resolving to the v02) is simply a bad idea. I would like your opinion on this.

Regards

Donat

PS : I'm not sure the issues section of your github repo is the best place for these kinds of questions. Please tell me if I should pm you instead.

LucaScheller commented 9 months ago

Hi Donat, once you a start layering files together, the asset identifier is "baked" into the layer.

So in your case you can't modify/treat the glass reference differently per table instance.

(You can do some asset identifier "hacking": Depending on how you write your resolver, you could make it create its asset path, that it uses for resolving (not the one on disk), relative to the layer that is referencing. This is what is built into the CachedResolver, see our docs here as an opt-in feature. This would not help you in your case though, since you need to resolve the same table asset differently per instance.

Basically it boils down to how you setup your pipeline. If there are instances of the same asset, that should get different sub-component treatments, then you'll need to create different assets/USD files (that internally refer to the same cache data), so that the identifiers are unique.

A good place for questions like this is also the USD Alliance Forum and the ASWF Slack Channels .

Cheers, Luca

LucaScheller commented 9 months ago

Marking as resolved for now :) Please re-open if you have further questions!