Howdy!
I have a test.usda
file that sublayers in some other USD files layer1.usda
, layer2.usda
, layer3.usda
, etc. These layerx.usda
files are always exported by the USD Python API, and all the contents are correct. When I do Usd.Stage.Open("test.usda")
to load the stage, all the layers are correctly composed into a single stage and I can access every prim from the stage. After that, some of these layer files are updated by other applications, and I wanted to use layer.Reload()
to reload only the layers that have been changed instead of reloading the entire stage, unfortunately that doesn’t seem to work well, it works for some layers, but not for others. For example, I have a layer file exported from Houdini which always throws the exception below when I reload it, I can’t even use Sdf.Layer.FindOrOpen()
or Usd.Stage.Open()
to load it separately, but Usd.Stage.Open("test.usda")
does pull in every single prim from it, which is weird.
pxr.Tf.ErrorException:
Error in 'textFileFormatYyerror' at line 3116 in file pxr/usd/sdf/textFileFormat.yy : 'syntax error at '' in </somePrim.primvars:st:indices> on line 268 in file /path/to/layer3.usda
'
There’s nothing particularly wrong on line 268, but it always fails on a line that starts with a primvar like primvars:st
or primvars:st:indices
. Also, for some layers I was getting a MemoryError
from Python, not sure what happened there.
It seems to me that the text parser is quite restrictive and Reload()
only works for very simple USD files like a light rig, so I have to use a different approach. Since the composition engine seems to be able to compose these layers without issue, I tried to make a copy of the layer’s USD file (to avoid conflicting layer identifiers), loaded it as a brand new Sdf layer, and then compose it on top of the layer stack:
shutil.copy("layer3.usda", "layer3_copy.usda")
newLayer = Sdf.Layer.FindOrOpen("layer3_copy.usda")
stage.GetSessionLayer().subLayerPaths.insert(0, newLayer.identifier)
But again, this doesn’t work, I was getting the same errors as before. And for layers that do work well with this approach, I’ve noticed that USD cannot send change notices properly after that so the renderer was not updating to reflect the changes, but that might be a bug in the rendering code which I haven’t investigated much.
As a last resort, I’ve given up on reloading a single layer so I decided to just reload the entire stage by calling stage.Reload()
, and that immediately gives me a SIGSEV
because the layer files have been changed externally.
I apologize for not having a simple reproducible case, the layer USD files are really huge so I can’t really post them here. Just as a general question though, what is the recommended way to reload an arbitrary layer without crashing the program? I don’t want to clear the entire stage from memory and load it again as if it was opened for the first time.