"Cannot insert duplicate registry entry for usd layer" when referencing the same object twice

Hello all,

I am having issues in Omniverse Code when I attempt to reference the same file in a scene in more than one place. If I do the following in vanilla USD and usdview, it works fine:

from pxr import Usd, UsdGeom

ref_path = "examples/top.geom.usd"

stage = Usd.Stage.CreateNew('test_references.usda')

for i in range(4):
    xf = UsdGeom.Xform.Define(stage, f'/Xform_{i}')
    xf.GetPrim().GetReferences().AddReference(ref_path)

stage.GetRootLayer().Save()

However if I do more or less the same in Omniverse (via the Script Editor):

from pxr import Usd, UsdGeom
import omni

ref_path = "./Workspace/learning/usd/examples/top.geom.usd"

stage = omni.usd.get_context().get_stage()

for i in range(4):
    xf = UsdGeom.Xform.Define(stage, f'/Xform_{i}')
    xf.GetPrim().GetReferences().AddReference(ref_path)

I get the following error:

2022-08-19 19:57:07  [Error] [omni.kit.app.plugin] [py stderr]: ErrorException: 
2022-08-19 19:57:07  [Error] [omni.kit.app.plugin] 	Error in 'pxrInternal_v0_20__pxrReserved__::Sdf_LayerRegistry::InsertOrUpdate' at line 155 in file /buildAgent/work/ca6c508eae419cf8/USD/pxr/usd/sdf/layerRegistry.cpp : 'Cannot insert duplicate registry entry for usd layer SdfLayer('Workspace/learning/usd/examples/top.geom.usd', 'Workspace/learning/usd/examples/top.geom.usd') over existing entry for usd layer SdfLayer('Workspace/learning/usd/examples/top.geom.usd', 'Workspace/learning/usd/examples/top.geom.usd')'

I can even open the file test_references.usda in OV Code with no issues. Did I make a mistake or could this be a bug? Is there an “Omniverse-safe” way of doing this?

Seems like the issue might actually be the use of relative paths. The code I posted previously works when I use absolute paths. This also seems to work.

import omni.kit.commands
from pxr import Usd, Sdf

ref_path = "/abs/path/to/top.geom.usd"
stage = omni.usd.get_context().get_stage()


for i in range(4):
    prim_path = f'/World/Xform_{i}'
    omni.kit.commands.execute('CreatePrimWithDefaultXform', prim_path=prim_path, prim_type='Xform', attributes={}, select_new_prim=False)
    omni.kit.commands.execute('AddReference', stage=stage, prim_path=Sdf.Path(prim_path), reference=Sdf.Reference(ref_path))

Hi Mason. I see someone on usd-interest reported a similar issue back in April using a similar version to Omniverse. I wonder if this is something fixed in newer versions of USD. I’m guessing you’re using USDView from the launcher? I’ll check to see if anyone knows more about this.

Huh. I actually can’t repro it.

Strange. I installed new versions and still am able to see the issue in both Code 2022.1.3 and Create 2022.2.0. I am on Ubuntu if that makes a difference.

To check in “vanilla” USD I actually used the pxr and usdview included in the nv_usd install in a Conda environment. I tried a few different USD files as well and had the same issue.

I also found that post on usd-interest and downloaded their files. They seem to open fine in both usdview and Omniverse. If I manually add two references to the same file in OV it also works fine. The only issue crops up for me while scripting, whether I’m using the pxr or omni.kit.commands methods and only when using relative paths.

Thanks for the additional info. Seems like a newer USD version isn’t necessarily the solution. I’ll check with the devs to see if they have any more ideas.

I thought I had a potential solution and started drafting a post, but I realized as I was writing it and testing on my end that I didn’t understand the problem correctly. In case it’s helpful though, I ran your snippet with an adjustment to ref_path on Code 2022.1.3 and it worked fine for me. Also for the record I am on Windows 10, in case it is an OS-specific problem.

from pxr import Usd, UsdGeom
import omni

ref_path = "./cubetest.usd"

stage = omni.usd.get_context().get_stage()

for i in range(4):
    xf = UsdGeom.Xform.Define(stage, f'/Xform_{i}')
    xf.GetPrim().GetReferences().AddReference(ref_path)

I get 4 cubes nested inside of 4 Xforms as expected.

I tried it on Code 2022.1.3 and Windows 10 and was able to reproduce the issue. However, I believe I discovered what was going on.

It seems this only occurs whenever I have opened a brand new file and have not saved yet. If I open a USD file (such as cubetest.usd) and run the script, I get the expected result. My guess is that since relative pathing is based on the opened USD file, if we haven’t explicitly opened any USD file it does not know how to define references in Omniverse.

Thanks Mason! I’m trying to get a hold of a Linux machine to try reproing again.