Sdf Namespace editing : 'Object already exists'?

Hello,

I am trying to perform some namespace edits using SDF - and I am hitting a strange (at least to me) issue.

Given the python code below, I am getting a “object already exists” error :

(False, [Sdf.NamespaceEditDetail(Sdf.NamespaceEditDetail.Error,Sdf.NamespaceEdit(Sdf.Path('/root{color=blue}sphere'),Sdf.Path('/root{tint=blue}sphere'),-1),'Object already exists')])

I’ve succesfully used similar code to namespace edit between variants of the same set, but now to a different set… no luck. Looking at the CanApply/Process code in cpp, it seems to just be calling “layer.GetObjectAtPath()”… I am not sure how it can possibly return something valid for /root{tint=blue}sphere' before the edit actually happens…?

Thanks in advance!


from pxr import Usd, Sdf

stage = Usd.Stage.CreateInMemory()
root_prim = stage.DefinePrim('/root')
vset = root_prim.GetVariantSets().AddVariantSet('color')
vset.AddVariant('red')
vset.AddVariant('blue')
vset.AddVariant('green')

vset.SetVariantSelection('blue')

with vset.GetVariantEditContext():
	blue_sphere = stage.DefinePrim('/root/sphere', 'Sphere')
	blue_sphere.CreateAttribute('size', Sdf.ValueTypeNames.Double).Set(2.0)

layer = stage.GetRootLayer()

Sdf.CreatePrimInLayer(layer, '/root{tint=blue}')

namespace_edits = Sdf.BatchNamespaceEdit()
namespace_edits.Add(Sdf.Path('/root{color=blue}sphere'), Sdf.Path('/root{tint=blue}sphere'))

print(layer.CanApply(namespace_edits))

OK I believe there is a bug here. I can work around the issue using an intermediate variant “tmp”.

from pxr import Usd, Sdf

stage = Usd.Stage.CreateInMemory()
root_prim = stage.DefinePrim('/root')
vset = root_prim.GetVariantSets().AddVariantSet('color')
vset.AddVariant('red')
vset.AddVariant('blue')
vset.AddVariant('green')

vset.SetVariantSelection('blue')

with vset.GetVariantEditContext():
	blue_sphere = stage.DefinePrim('/root/sphere', 'Sphere')
	blue_sphere.CreateAttribute('size', Sdf.ValueTypeNames.Double).Set(2.0)

layer = stage.GetRootLayer()

Sdf.CreatePrimInLayer(layer, '/root{tint=tmp}')

namespace_edits = Sdf.BatchNamespaceEdit()
namespace_edits.Add(Sdf.Path('/root{color=blue}sphere'), Sdf.Path('/root{tint=tmp}sphere'))
layer.Apply(namespace_edits)

variant_set = layer.GetPrimAtPath('/root').variantSets['color']
variant_set.RemoveVariant(variant_set.variants['blue'])

Sdf.CreatePrimInLayer(layer, '/root{tint=blue}')

namespace_edits = Sdf.BatchNamespaceEdit()
namespace_edits.Add(Sdf.Path('/root{tint=tmp}sphere'), Sdf.Path('/root{tint=blue}sphere'))
print(layer.CanApply(namespace_edits))
layer.Apply(namespace_edits)

It sees that a variant named blue already exists… but it doesnt realise that it is for a different variant set - and therefor should not collide.

I will log an issue.

Logged here Variant set namespace editing fails on erroneous "object already exists" · Issue #3658 · PixarAnimationStudios/OpenUSD · GitHub

On the surface it sure does sound like a bug. Thanks for filing the Issue - we’ll have a look! Also, it makes me recall that we did find and fix some variant-related bugs as part of the namespace editing work over the past year - I didn’t see in the Issue which version of OpenUSD you were using?

Ha, indeed i have not tried the very latest release. I am on 24.11. I will try and close my issue if already fixed. Thanks.

Still a problem in 25.05 :

(False, [Sdf.NamespaceEditDetail(Sdf.NamespaceEditDetail.Error,Sdf.NamespaceEdit(Sdf.Path(‘/root{color=blue}sphere’),Sdf.Path(‘/root{tint=blue}sphere’),-1),‘Object already exists’)])