Reordering references?

Hi,

I’m doing some tests with references, and what I’m trying to do is basically, assuming I have the following scene (where nested_references.usda is the main stage):

// nester_references.usda

    #usda 1.0

    over "Xform" (
        prepend references = [
            @./ref_a.usda@,
            @./ref_b.usda@
        ]
    )
    {
    }

// ref_a.usda

    #usda 1.0
    (
        defaultPrim = "RefARoot"
    )

    over "RefARoot" (
        prepend references = @./sub_ref.usda@
    )
    {
        def Sphere "Sphere"
        {
        }
    }


// ref_b.usda

    #usda 1.0
    (
        defaultPrim = "RefBRoot"
    )

    def "RefBRoot"
    {
        over "NestedRef" (
            prepend references = @./sub_ref.usda@</Capsule>
        )
        {
            def Cone "Cone"
            {
            }
        }
    }


// sub_ref.usda

    #usda 1.0
    (
        defaultPrim = "SubRefRoot"
    )

    def "Xform"
    {
        def Cube "Cube"
        {
        }
    }

    def Xform "Capsule"
    {
        def Capsule "CapsuleShape"
        {
        }
    }

What I’d like to do in this case is to invert ./ref_a.usda and ./ref_b.usda on the /Xform prim. It feels like this should be possible, but I’m lost in all the various abstractions like SdfListEditor, SdfListEditorProxy, etc. and also how to reliably retrieve the initial list of references…

Right now, I’m getting the list of reference that interests me like so:

static SdfReferenceVector
get_references(const UsdPrim& prim)
{
    UsdPrimCompositionQuery::Filter filter;
    filter.arcTypeFilter        = UsdPrimCompositionQuery::ArcTypeFilter::Reference;
    filter.dependencyTypeFilter = UsdPrimCompositionQuery::DependencyTypeFilter::Direct;
    filter.arcIntroducedFilter  = UsdPrimCompositionQuery::ArcIntroducedFilter::IntroducedInRootLayerPrimSpec;

    SdfReferenceVector      references;
    SdfReferenceEditorProxy editor;
    SdfReference            reference;
    for (const UsdPrimCompositionQueryArc& arc : UsdPrimCompositionQuery(prim, filter).GetCompositionArcs()) {
        if (arc.GetIntroducingListEditor(&editor, &reference)) {
            references.push_back(reference);
        }
    }

    return references;
}

But that feels horribly wrong. In that case (using this filter) it feels like I should be able to just get the SdfReferenceEditorProxy on the first arc of the query, and use that directly (SdfReferenceEditorProxy::GetAppliedItems), but I’m not sure.

I’ve also found the helper SdfReferenceEditorProxy SdfGetReferenceEditorProxy(const SdfSpecHandle& spec, const TfToken& referenceField);. But given a UsdPrim that points to /Xform in my stage, I have no idea how to reliably retrieve the spec that holds the references. I tried getting the root Pcp node from the prim index, but that root node has a layer stack, not a single one. It feels like for Pcp root nodes, that stack is always 1 layer, but again, I’m not sure?

Long story short: I’m a bit lost, and I would really appreciate any help regarding references :smiley:
Thanks in advance for any pointer to helpful documentation, examples, etc.!

Damien.

Hi @dcourtois , it’s not a matter of API - what you’re trying to do cannot be done, as it would violate reference encapsulation . You can only reorder references that appear on same-named specs of stronger and weaker layers within a layerStack, as explained in this FAQ entry - please lmk if this needs to be explained better?

Cheers,
–spiff

Apologies - I misunderstood what you were trying to do. Yes, if you are directly editing the Spec in the root layer, you should be able to update the references. I also find the SdfListEditor framework challenging sometimes.. Can I suggest that once you have the new order of references that you want, you try using the UsdReferences API, with the stage’s EditTarget set to the root layer (or whatever layer contains the primSpec)?