Which layers will UsdNamespaceEditor change

While working with UsdNamespaceEditor I came across a situation that surprised me. I wondered if it’s due to UsdNamespaceEditor still being a work in-progress or if the behavior I’m seeing is intended and is the way UsdNamespaceEditor will function going forward.

I have a simple scene constructed from two files, root_layer.usda and sub_layer.usda.

root_layer.usda is:

#usda 1.0

(
    subLayers = [
        @./sub_layer.usda@
    ]
)

def Sphere "someSphere"
{
}

And sub_layer.usda is:

#usda 1.0

def Cube "someBox"
{
}

Using the following code snippet I define a new parent for /someSphere and /someBox and use UsdNamespaceEditor to move them into it:

from pxr import Usd, UsdGeom

stage = Usd.Stage.Open('root_layer.usda')
stage.SetEditTarget(stage.GetRootLayer())

# Define a new parent prim for the sphere and the box
xformAPI = UsdGeom.Xform.Define(stage, '/newParent')
xformPrim = xformAPI.GetPrim()

spherePrim = stage.GetPrimAtPath("/someSphere")
boxPrim = stage.GetPrimAtPath("/someBox")

# Move /someSphere to /newParent first
editor1 = Usd.NamespaceEditor(stage)
editor1.ReparentPrim(spherePrim, xformPrim)
editor1.ApplyEdits()

# Move /someBox to /newParent second
editor2 = Usd.NamespaceEditor(stage)
editor2.ReparentPrim(boxPrim, xformPrim)
editor2.ApplyEdits()

stage.Save()

When I originally did this experiment I thought to myself, “I’ve set the stage’s edit target to root_layer.usda so I will only see changes in root_layer.usda. I assume the movement of /someBox to /newParent will be accomplished in root_layer.usda with a relocates. Or something like that…”

But when I run the code I get the following.

Resulting root_layer.usda:

#usda 1.0
(
    subLayers = [
        @./sub_layer.usda@
    ]
)

def Xform "newParent"
{
    def Sphere "someSphere"
    {
    }
}

Resulting sub_layer.usda:

#usda 1.0

over "newParent"
{
    def Cube "someBox"
    {
    }
}

The surprising part was that even though I’d set the stage’s edit target to root_layer.usda, changes were also made to sub_layer.usda. But having reread the namespace editing documentation I’ve convinced myself that this is probably the intended behavior since there is a reference to relocates working with remote layer stacks but nothing is said about local layer stacks.

As development continues on UsdNamespaceEditor, will it continue to make changes across the layers of a stage’s local layer stack and will not confine its edits to the stage’s edit target layer?

Note: This question is related to Dhruv’s question here as it was while tracking UsdNamespaceEditor changes for undo that I discovered this behavior.

That is indeed the correct and desired behavior, because we do not want to futz with changing strength ordering of opinions by moving specs around between layers in the layerStack. So, each layer in the layerStack that has “before namespace” opinions, is updated to have “after namespace” within itself. Also, as the example at the top of the Namespace Editing user-guide describes even more simply, if you want to delete a prim, you need to do so from every layer in which it appears.

And just in case you were thinking maybe to see a “relocate” in the stronger layer… relocates can’t apply to specs in the local layerStack - only to prims/namespace coming in over composition arcs.

Thank you for clarifying, @spiff.

I had originally been thinking / hoping I would see a relocate in the edit target layer but I now understand why that can’t happen.