# How to properly reload reference and payloads?

**URL:** <https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640>\
**Category:** USD\
**Tags:** cpp\
**Created:** [June 27, 2024, 8:48pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640 "2024-06-27T20:48:39Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [June 27, 2024, 8:48pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/1 "2024-06-27T20:48:39Z")

</div>

Hello,  
I’m looking to implement a simple Reload function (for reference or payload - coming from another usd file). Meaning, given a prim that has a payload or reference in it, what would be the best way to reload (for the cases where the reference has changed outside)?

I tried the simple way:

```auto
prim.GetStage()->Load(_prim.GetPath(), UsdLoadWithDescendants);

```

This didn’t work, my guess is that it can’t resolve that “prim” in this case it’s another file?

I also tried this other way:

```auto
for (const auto& child : _prim.GetPrimIndex().GetRootNode().GetChildrenRange()) {
    child.GetLayerStack()->GetIdentifier().rootLayer->Reload();
}

```

This approach a got the new changes, but this applies to the entire layer, not only a prim? So if I had several prims, it would “reload” all of them.

Would anyone have an idea for a better solution for this?  
Thanks in advance

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [June 28, 2024, 12:28am UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/2 "2024-06-28T00:28:16Z")

</div>

Is [UsdStage::Reload()](https://openusd.org/release/api/class_usd_stage.html#abf674de32ff446b3f2323b88adce89f8) too large a granularity for you? It will find and reload all (and only) the references/payloads/subLayers whose timestamps have changed.

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [June 28, 2024, 12:34am UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/3 "2024-06-28T00:34:04Z")

</div>

Sorry - missed the end of your post. USD reloads by _layer_, **and** layers are cached and shared. So it’s not possible to either:  
a) reload a reference and have the new data apply just to a particular prim that references the same layer, but leave _other_ prims that reference the same layer unchanged  
b) have just some of the descendant prims defined by the referenced layer be updated, but not others, when reloading the referenced layer (couldn’t tell if you were asking about this case).

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [June 28, 2024, 1:14pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/4 "2024-06-28T13:14:02Z")

</div>

Hi @spiff ,  
Thanks for the response. Your second replies explains the behavior that I’m seeing. It makes sense now, thank you.

I would use UsdStage::Reload if I could, but it doesn’t seem to work for me. Are there conditions or assumptions that would make it fail?

```auto
stage
- prim1 (payload file2.usd)

```

Calling :

```auto
prim1->GetStage()->Reload(prim1.GetPath(), UsdLoadWithDescendants)

```

Doesn’t seem to reload anything.

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [June 28, 2024, 9:36pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/5 "2024-06-28T21:36:58Z")

</div>

Reload() will only do anything if the ArResolver determines the asset has been updated. The ArDefaultResolver uses `ArFilesystemAsset::GetModificationTimestamp()` to make that determination, comparing with the last modification time when the file asset was initially read (or last Reloaded)

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [July 2, 2024, 3:35pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/6 "2024-07-02T15:35:09Z")

</div>

Hi @spiff,  
I was able to play a bit more with this.  
The stage-\>Reload() doesn’t work for us. We would like a little bit more control over what the user choose to reload.

The following code works for to reload a certain `_prim` layer:

```auto
for (const auto& child : _prim.GetPrimIndex().GetRootNode().GetChildrenRange()) {
    child.GetLayerStack()->GetIdentifier().rootLayer->Reload();
}

```

However, if that `_prim` reference has any other child reference, it won’t reload those. Is that expected?

---

<div class="post-metadata">

**Author:** ![blevin](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@blevin](https://forum.aousd.org/u/blevin)\
**Post date:** [July 3, 2024, 3:43pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/7 "2024-07-03T15:43:10Z")

</div>

Hi @barbalt,

I think it will be a little tricky to do what you are asking for with the existing Python API. There are considerations of efficiency (ex: we don’t want to reload each layer one by one and update the scene after each) and correctness (ex: we want to re-try reference arcs to layers that could not be resolved previously, which means they would not be part of the Prim Index).

Would you mind filing a request on the OpenUSD github about this?

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [July 3, 2024, 5:19pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/8 "2024-07-03T17:19:58Z")

</div>

Hi @blevin , thank you for the reply!

I’ll make a simple scenario just to clarify that this is the case. Imagine the I open a stage with the following city district file:

`city_district.usd`:

```auto
def Xform "city_district" (
    kind = "assembly"
)
{
    def Xform "skatepark" (
        prepend references = @skatepark.usd@
    )
    {
    }
}

```

Then `skatepark.usd` file is:

```auto
def Xform "skatepark" (
    kind = "assembly"
)
{
    def Xform "ramp" (
        prepend payload = @ramp.usd@
        variants = {
            string type = "ramp2"
        }
    )
    {
        double3 xformOp:translate = (0, 0, -588.8887136544495)
        uniform token[] xformOpOrder = ["xformOp:translate"]
    }
}

```

And lastly `ramp.usd` is just a regular mesh.

In the example above, if I update the ramp.usd file, then reload the skatepark prim on the city\_district, it won’t update to the newest changes of ramp.usd.  
The same seems to be true for sublayers. If we load city\_district as a stage and reload that root layer, it still won’t bring in the changes I’ve made to ramp.usd.  
That’s the currently expected behavior?

Thanks once again for your time

---

<div class="post-metadata">

**Author:** ![blevin](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@blevin](https://forum.aousd.org/u/blevin)\
**Post date:** [July 3, 2024, 6:13pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/9 "2024-07-03T18:13:57Z")

</div>

> if I update the ramp.usd file, then reload the skatepark prim on the city\_district, it won’t update to the newest changes of ramp.usd

If you mean running the `for()` loop code above with `_prim` set to the skatepark prim, yes, that is correct.

The reason is that the prim index for `</city_district/skatepark>` does not contain any details about child prims, such as `</city_district/skatepark/ramp>`.

So, one of the things a fuller implementation of a “reload prim” or “reload model” API would do is to also traverse child prims to discover additional scene description used by them. This could use `UsdPrim::GetDescendants()`.

You would also want to reload all layers in each used layer stack, not only root layer (`PcpLayerStack::GetLayers()`).

Last, you would want to do this as two steps: a first pass to collect a set of layers (ex: a `std::set<SdfLayerHandle>`), then a pass to reload them all in one batch with `SdfLayer::ReloadLayers(layerSet)`.

That should get you close, but it wouldn’t handle the case of re-trying reference arcs that failed to resolve previously, such as if there was a typo and it had been accidentally an uppercase `Ramp.usd`.

> If we load city\_district as a stage and reload that root layer, it still won’t bring in the changes I’ve made to ramp.usd

Yes, that is correct. Reloading a layer only refreshes the contents of that layer; any other layers that had already been loaded will not be updated. If the new content of the `city_district.usd` layer includes references to new layers that had not previously been used, then those will be loaded.

hope this helps,  
-B

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [July 3, 2024, 6:22pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/10 "2024-07-03T18:22:10Z")

</div>

This a great and detailed explanation.  
Thank you very much.

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [July 5, 2024, 7:10pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/11 "2024-07-05T19:10:52Z")

</div>

Hello @blevin ,  
Once again thank you so much for help. I tried following the steps you suggested and still could only get the immediate references to reload. Anything that were being referenced by those references stay as they were after reload.

I figured I would share some of the things I tried:

I tried using UsdPrimCompositionQuery

```auto
UsdPrimCompositionQuery::Filter filter;
filter.arcTypeFilter = UsdPrimCompositionQuery::ArcTypeFilter::ReferenceOrPayload;
filter.dependencyTypeFilter = UsdPrimCompositionQuery::DependencyTypeFilter::Direct;

auto query = UsdPrimCompositionQuery(_prim);
query.SetFilter(filter);
for (auto arc : query.GetCompositionArcs()) {
    layersHandle.emplace(arc.GetTargetLayer());
}

SdfLayer::ReloadLayers(layersHandle);

```

Then I tried with descendants

```auto
for (const UsdPrim& descendant : _prim.GetDescendants()) {
    for (auto l : descendant.GetPrimIndex().GetRootNode().GetLayerStack()->GetLayers()) {
        layersHandle.emplace(l);
    }
}

SdfLayer::ReloadLayers(layersHandle);

```

I’m willing to try any other suggestions, but if none is available, I appreciate all the help.

Thank you

---

<div class="post-metadata">

**Author:** ![blevin](https://avatars.discourse-cdn.com/v4/letter/b/ed655f/32.png) [@blevin](https://forum.aousd.org/u/blevin)\
**Post date:** [July 8, 2024, 3:24pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/12 "2024-07-08T15:24:35Z")

</div>

Hi @barbalt, in your second snippet looping over descendants, you’ll need to use a full PrimIndex traversal, and insert every layer in each node’s layer stack.

In addition, the range returned by UsdPrim::GetDescendants() does not include the given prim, so you’ll need to handle that as well.

Something like this:

```auto
std::set<SdfLayerHandle> layerSet;

// Handle prim:
// For each prim index node (i.e., composition arc) in prim...
for (const auto& node : _prim.GetPrimIndex().GetNodeRange()) {
    // For each layer in the layer stack used by the composition arc...
    for (const auto& layer: node.GetLayerStack()->GetLayers()) {
        // ...add it to the set
        layerSet.insert(layer);
    }
}

// Next, handle prim's descendants the same way
for (const UsdPrim& descendant : _prim.GetDescendants()) {
    for (const auto& node : descendant.GetPrimIndex().GetNodeRange()) {
        for (const auto& layer: node.GetLayerStack()->GetLayers()) {
            layerSet.insert(layer);
        }
    }
}

// Reload all layers discovered to be in-use by this prim and its descendants
SdfLayer::ReloadLayers(layerSet);

```

If you prefer, it should be possible to use UsdPrimCompositionQuery instead of traversing prim.GetPrimIndex().GetNodeRange() here, but note that you’ll still need to access the node in each arc to pull on its full layer stack; GetTargetLayer() only returns the root layer of the layer stack, not any sublayers.

hope this helps,  
-B

---

<div class="post-metadata">

**Author:** ![barbalt](https://avatars.discourse-cdn.com/v4/letter/b/3bc359/32.png) [@barbalt](https://forum.aousd.org/u/barbalt)\
**Post date:** [July 8, 2024, 9:12pm UTC](https://forum.aousd.org/t/how-to-properly-reload-reference-and-payloads/1640/13 "2024-07-08T21:12:30Z")

</div>

This worked flawlessly! Thank you so much for the help.
