Why does editableStage() only work in pythonscript LOP

   456   3   0
User Avatar
Member
3 posts
Joined: March 2021
Offline
Hello!

Hoping someone can explain the reasoning/whats going on for a better understanding of Solaris.

If I try to run the following code just in the python script editor (or from an external process which is what I was actually trying to achieve)

from pxr import UsdRender
stage = hou.pwd().editableStage()
base_path = r'''test.$F4.exr'''
for prim in stage.Traverse():
    if prim.IsA(UsdRender.Product):
        product = UsdRender.Product(prim)
        product.GetProductNameAttr().Set(base_path)

It will error as the hou.pwd().editableStage() will return None. However, the same code works fine when put inside a pythonscript node.

Currently our design is going to have to be to generate pythonscript nodes in users scene to make stage edits, and delete the nodes after, I wanted to check my understanding is correct and you cannot edit the stage any other way?

If so, why is that?

Thanks,
L
User Avatar
Member
42 posts
Joined: Jan. 2024
Offline
Having access to an editable stage from a node - outside of a context that is actually inside the Houdini graph makes little sense, because you'll basically end up altering the in-memory USD stage even though it's not actually a 'change' occurring from Houdini's computational graph. As such, you've then somehow altered the USD stage in memory without it being done by what Houdini produced. An edit that will 1) be confusing because suddenly you may see something in Houdini that it doesn't actually evaluate to and 2) as soon as the graph re-evaluates it will be lost.

I'm unsure why in particular you're trying to do "stage edits" that wouldn't then 'persist' inside of Houdini since as soon as the graph would re-evaluate your change would be immediately lost as Houdini has now generated the full USD stage. As such, this makes me think you're using this for some temporary export process that does not go through a regular Houdini ROP?

Overall you're best off generating a Houdini graph that makes the edits you want, which can be just a heavy Python LOP calling a function from your pipeline - if you want to end up still using that data inside of Houdini.

If not, then likely you may want to do `LopNode.stage()` instead of calling `LopNode.editableStage()` so that you can access the stage. Then technically if you do want a completely managed 'local' version of the stage you'd need to remap all Sdf Layers to copies of your own so you're still not touching any managed by Houdini itself.

Making such an in-memory copy can be done similar to this: https://github.com/ynput/ayon-houdini/blob/3fcb1641d60e72725d684c0a9d7910c341da6485/client/ayon_houdini/plugins/publish/collect_usd_rop_layer_and_stage.py#L158-L175. [github.com]

Be aware though that technically there I'm making anonymous copies which may mean that any 'relative asset paths' may not end up evaluating to what you'd expect because technically those anonymous layers are not anchored on disk.

I'm sure there must be better ways to do this - so I'm all ears.
Edited by colorbleed - July 22, 2025 10:11:35
User Avatar
Member
3 posts
Joined: March 2021
Offline
Thanks so much for your thoughts here! What you've mentioned here

colorbleed
I'm unsure why in particular you're trying to do "stage edits" that wouldn't then 'persist' inside of Houdini since as soon as the graph would re-evaluate your change would be immediately lost as Houdini has now generated the full USD stage. As such, this makes me think you're using this for some temporary export process that does not go through a regular Houdini ROP?

is exactly it, we've hi-jacked the usd_renderrop to submit solaris renders to the farm, using the usd_renderrop only to generate the USD file (by setting the runcommand parm to 0). We then run husk on the generated USD file to actually do the render.

We don't want artists to care about the productName and output paths being correct in their work scene, as our AMS has to figure out the next available version and form the correct publish path, so we calculate that on the farm, and force update those paths in the published scene.

We could of course edit the exported USD file after its come out of Houdini, just with the USD api completely outside houdini, but this adds extra process time on our farm as it has to spin up new boxes to do this etc (thats a whole other problem I won't get into here)

So say we have to stick with doing this inside the houdini farm process when the USD is written out to disk, I think putting this all inside a pythonscript LOP is the only way to do what we need to from the sounds of it!

I think maybe editing the USD file directly is likely the better way to do what we want in the long run, but we've just got to sort out the farm first...
User Avatar
Member
42 posts
Joined: Jan. 2024
Offline
> We could of course edit the exported USD file after its come out of Houdini, just with the USD api completely outside houdini, but this adds extra process time on our farm as it has to spin up new boxes to do this etc (thats a whole other problem I won't get into here)

With what you're trying to do it may be worth it to implement a custom Output Processor perhaps?
  • Quick Links