Skip to content

References with empty asset and obect path - intended to work, or should error? (USD Spec 1.0.1 divergence) #3954

@pmolodo

Description

@pmolodo

The AOUSD Core Specification v1.0.1, section 7.6.2.3.1, has this to say regarding reference targets:

Targets could be implemented or stored as a variant. It may also be implemented as two optional subfields but is only valid when at least one of the subfields is set.

Thus, according to the spec, a reference with an empty asset and objectPath should be considered invalid.

However, OpenUSD currently treats such references as valid, as it does not validation on read or creation, and a null field for either property has a well defined meaning:

  • a null asset means use the authoring local layer stack
  • a null objectPath means use the default prim in the layer stack

Therefore, a reference with neither asset or objectPath targets the defaultPrim on the authoring layer stack.

Such references can be created via the USD api, in both C++ and python - ie, here's some python code to create a null/null reference:

make_null_null_reference.py

from pxr import Sdf, Usd

# ============================================

stage = Usd.Stage.CreateInMemory()
rootLayer = stage.GetRootLayer()
assert rootLayer == stage.GetEditTarget().GetLayer()

primA = stage.DefinePrim("/A", "Scope")
primB = stage.DefinePrim("/B")
stage.SetDefaultPrim(primA)
primB.GetReferences().AddInternalReference(Sdf.Path.emptyPath)

print(rootLayer.ExportToString())

rootLayer.Export("reference_asset-no_path-no.usda")
rootLayer.Export("reference_asset-no_path-no.usdc")

del stage, rootLayer, primA, primB

# ============================================

layer = Sdf.Layer.FindOrOpen("reference_asset-no_path-no.usda")
specB = layer.GetPrimAtPath("/B")

appliedRefs = specB.referenceList.GetAppliedItems()
assert len(appliedRefs) == 1
appliedRef = appliedRefs[0]

print("ref asset path: ", appliedRef.assetPath)
print("ref prim path: ", appliedRef.primPath)

Such references can also be written out in both .usda and .usdc formats - in usda, the reference is written as, ie:,

def "B" (
    prepend references = <>
)

They can also be read back in from both .usda and .usdc without error - though reading such a reference from .usda DOES raise a warning about an Ill-formed SdfPath:

Warning: in SdfPath at line 127 of /opt/USD/pxr/usd/sdf/path.cpp -- Ill-formed SdfPath <>: :1:1: parse error matching pxrInternal_v0_25_5__pxrReserved__::Sdf_PathParser::Path

Is this behavior was intentional? If not, would you consider consider checking for and disallowing such references, to align better with the spec? Or should the spec be ammended to match OpenUSD behavior?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions