From a given pxr.Usd.Prim
I’d like to be able to query the current active references and payloads. It seems that prim.GetReferences()
and prim.GetPayloads()
ironically do not allow to provide that, but allow to add/remove references (generating new opinions basically) instead of detecting the resolved opinion.
The documentation states to maybe look into the usage of a Usd.PrimCompositionQuery
, for example using Usd.PrimCompositionQuery.GetDirectReferences(prim).GetCompositionArcs()
but somehow those always kept returning empty lists for me.
The only way I could find was maybe going through:
stack = prim.GetPrimStack()
references = []
payloads = []
for prim_spec in stack:
for reference in prim_spec.referenceList.GetAppliedItems():
references.append(reference)
for payload in prim_spec.payloadList.GetAppliedItems():
payloads.append(payload)
But as far as I’m aware since that’s the lower level SDF API that wouldn’t actually resolve to the resulting composed references and payloads, but only the resulting apply of that particular Sdf.PrimSpec
per Sdf.Layer
.
Then I’d also like to have easy access to be able to remove the opinions in a layer as well. As far as I can see I must then manually go through all list change types for payloadList
and referenceList
.
Something like:
from dataclasses import dataclass
LIST_ATTRS = ['addedItems', 'appendedItems', 'deletedItems', 'explicitItems',
'orderedItems', 'prependedItems']
@dataclass
class ListProxyItem:
proxy: object
value: object
def update(self, new_value):
""Replace value in proxy with a new value""
index = self.proxy.find(self.value)
self.proxy[index] = new_value
self.value = new_value
def delete(self):
"""Remove self from the proxy's entries"""
proxy = self.proxy
proxy[:] = [x for x in proxy if x != self.value]
stack = prim.GetPrimStack()
items = []
for prim_spec in stack:
for key in LIST_ATTRS:
proxy = getattr(prim_spec.referencesList, key)
for reference in proxy:
item = ListProxyItem(proxy=proxy, value=reference)
items.append(item)
# So that then I could do e.g.
item = items[0]
item.update(Sdf.Reference(assetPath="new_identfier"))
item.delete() # removing the entry
Are there better Python patterns or USD Python API usage to go about this?