Is it illegal to create in-memory Usd.Stage or anonymous Sdf.Layer from inside a Python Lop node? I am looking to know what should be avoided inside a Python Lop node.
Using a snippet similar to this one below from a Python Lop node, everything looks good from inside Houdini. But once I try to render through Husk, some un-explicable things happen.
frompxrimportSdf,Usdbase_layer=Sdf.Layer.FindOrOpen('file.usd')top_layer=Sdf.Layer.CreateAnonymous()## Do some edits on the top_layer using the Sdf api.#memory_stage=Usd.Stage.CreateInMemory()root_layer=memory_stage.GetRootLayer()root_layer.subLayerPaths.append(base_layer.identifier)root_layer.subLayerPaths.append(top_layer.identifier)root_layer.defaultPrim=base_layer.defaultPrimnode=hou.pwd()stage=node.editableStage()prim=stage.DefinePrim('/my/prim','Xform')prim.GetReferences().AddReference(root_layer.identifier)
Opening the usd file exported by Husk and inspecting the composition of an affected prim in houdini, i see some sublayers identified as "<unknown name>".
Looking forward to get some insights on this. Thank you in advance!
I was able to find an answer by looking at the hou.LopNode.addHeldLayer() documentation. The important part is using loputils.createPythonLayer() instead of Sdf.Layer.CreateAnonymous().
From what I can understand it does 2 things: - It adds some metadata to the layer that helps Houdini know what to do with it on export. - It prevents the Sdf.Layer to be deleted by USD too early. It does so under the hood by linking it to the hou.LopNode using the hou.LopNode.addHeldLayer() method.
Here is the updated example. As a bonus of these changes, staying within the Sdf api cooks quicker for my real use case.
importhouimportloputilsfrompxrimportSdflop_node=hou.pwd()editable_layer=lop_node.editableLayer()# Open/Create Layersbase_layer=Sdf.Layer.FindOrOpen('file.usd')top_layer=loputils.createPythonLayer(lop_node)## Do some edits on the top_layer using the Sdf api.## Merge Layersroot_layer=loputils.createPythonLayer(lop_node)root_layer.subLayerPaths.append(base_layer.identifier)root_layer.subLayerPaths.append(top_layer.identifier)root_layer.defaultPrim=base_layer.defaultPrim# Define Primprim_spec=Sdf.CreatePrimInLayer(editable_layer,'/my/prim')prim_spec.specifier=Sdf.SpecifierDefprim_spec.typeName="Xform"# Add Referencereference=Sdf.Reference(root_layer.identifier)prim_spec.referenceList.appendedItems=[reference]