# Ordering of list operations across arcs

**URL:** <https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808>\
**Category:** USD\
**Created:** [August 27, 2024, 4:23pm UTC](https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808 "2024-08-27T16:23:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nvmkuruc](https://avatars.discourse-cdn.com/v4/letter/n/76d3ee/32.png) [@nvmkuruc](https://forum.aousd.org/u/nvmkuruc)\
**Post date:** [August 27, 2024, 4:23pm UTC](https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808/1 "2024-08-27T16:23:13Z")

</div>

Hello-- we wanted to get some clarification on the following behavior. There are two layers in this example.

component.usda

```auto
#usda 1.0

class "class_a" {}

def "child" (inherits = </class_a>) {}

```

assembly.usda

```auto
#usda 1.0

class "class_a" {}
class "class_b" {}

def "append" (
        append inherits = </class_b>
        references = @./component.usda@</child>) {}

def "explicit_remove" (
        inherits = </class_b>
        references = @./component.usda@</child>) {}

def "explicit_order" (
         inherits = [</class_a>, </class_b>]
         references = @./component.usda@</child>) {}

```

If I open the assembly.usda in python as stage `s`, I get the following results.

```auto
>>> s.GetPrimAtPath('/append').GetPrimStack()
[Sdf.Find('assembly.usda', '/append'), Sdf.Find('assembly.usda', '/class_b'), Sdf.Find('assembly.usda', '/class_a'), Sdf.Find('component.usda', '/child'), Sdf.Find('component.usda', '/class_a')]

```

Even though we use `append`, the opinions in `/class_b` are stronger than those in `class_a` on the `assembly.usda` layer.

```auto
>>> s.GetPrimAtPath('/explicit_remove').GetPrimStack()
[Sdf.Find('assembly.usda', '/explicit_remove'), Sdf.Find('assembly.usda', '/class_b'), Sdf.Find('assembly.usda', '/class_a'), Sdf.Find('component.usda', '/child'), Sdf.Find('component.usda', '/class_a')]

```

Even though we explicitly set the `inherits` opinion to `/class_b`, `/class_a` still contributes opinions from `assembly.usda`.

```auto
>>> s.GetPrimAtPath('/explicit_order').GetPrimStack()
[Sdf.Find('assembly.usda', '/explicit_order'), Sdf.Find('assembly.usda', '/class_a'), Sdf.Find('assembly.usda', '/class_b'), Sdf.Find('component.usda', '/child'), Sdf.Find('component.usda', '/class_a')]

```

However, if we include `class_a` and `class_b` explicitly, the order changes.

We’re trying to reason about this-- is `class_a` just taking on the strength order of its referencing arc in the prim stack (which is always weaker than inherits) unless explicitly specified?

---

<div class="post-metadata">

**Author:** ![paoloemilioselva](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/paoloemilioselva/32/267_2.png) [@paoloemilioselva](https://forum.aousd.org/u/paoloemilioselva)\
**Post date:** [August 28, 2024, 6:59am UTC](https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808/2 "2024-08-28T06:59:21Z")

</div>

nice post and I always wanted to find the exact answer to this.

And now I’m actually relying on this behaviour, in what we are building 🙂  
Starting with the idea that “all edits should be coming from inherits” so that they work nicely with instanceable.

From what I understand, there are a few things happening here.

List-edits are not there after crossing composition arcs, they mostly apply with direct sublayering, as a behaviour I’ve seen on core metadata (not sure about relationships), and probably due to how it composes

(side note: is this link broken?)  
[https://openusd.org/release/api/\_usd\_\_page\_\_object\_model.html#Usd\_OM\_ListOps](https://openusd.org/release/api/_usd __page__ object_model.html#Usd_OM_ListOps)

When referencing component.usda, you are not really bringing class\_a prim from it, you get the embedded result of the inherit from it, but not the class itself, which means that you are not going to be able to remove that inheritance from the referenced component.usda with anything from the assembly.usda (not even with an explicit delete, via api sure, but artists don’t do that 🙂 ).

But you do “inherit” the fact that, in a weaker “layer in the stack” it is “inheriting” from “class\_a”, so that lets you add “class\_a” in assembly.usda and still “inherit from that”, again, no matter what you do (like delete again), it will always inherit from class\_a, because that applies only to the inherits before the reference is applied.

And this gives you the ability to say that no matter in which way the inherit is coming with the assembly.usda (class\_b, pre or app) you can always have your stronger opinion in the file that is referencing your component.usda.

component.usda could have a cube that inherits its “red” color from its class\_a.  
assembly.usda can’t change the fact that the cube is “red” (as inheriting from its embedded class\_a).  
But assembly.usda can re-define class\_a with a new color, and nothing else needed (no new inherits) and now the new color comes from the class\_a in assembly.usda.  
Or you can also have the new color-value coming from class\_b, and no matter how you inherit it in assembly.usda (pre/app), class\_b will always be stronger.

This means that “city-blocks with their own inherits” can be referenced in “cityA” with new classes and no new overs for new inherits and you can provide your new “classes edits”, plus having extra edits from more explicit new inherits in cityA if needed.

Sorry for the long reply…

If my assumptions are based on the wrong understanding, please correct me, but don’t tell me it is a bug and it shouldn’t behave like it is…please… 😅

---

<div class="post-metadata">

**Author:** ![paoloemilioselva](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/paoloemilioselva/32/267_2.png) [@paoloemilioselva](https://forum.aousd.org/u/paoloemilioselva)\
**Post date:** [August 28, 2024, 8:03am UTC](https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808/3 "2024-08-28T08:03:47Z")

</div>

Now that I think about this a bit more… I remember some different behaviour in older usd versions… or am I just remembering this wrong ?! Maybe there was a purpose involved… I think I need to test this further before we fully go with it… just to make sure I’m not relying on something that’s not supposed to be happening.  
Sorry to hijack your initial question, but I assume you also expect this behaviour, and just wanted to confirm why this is happening, right ?

I’ve got a few example files to support what I described earlier.

Drop those files at the root of your assets-repo folder, so that they can pick up the Teapot asset and load “teapot\_city.usda”.

[teapot\_asset.usda](https://forum.aousd.org/uploads/short-url/3x7q4YRnEpVG9WFjyaYm9sYF0hk.usda) (406 Bytes)  
[teapot\_block.usda](https://forum.aousd.org/uploads/short-url/u7I38ijLySzdIVNJ8rje3MKdLdV.usda) (1.8 KB)  
[teapot\_city.usda](https://forum.aousd.org/uploads/short-url/m5YbcAQyTevHSb3OFUdJXe3odMC.usda) (1.4 KB)  
[teapot\_no\_lid.usda](https://forum.aousd.org/uploads/short-url/zBxfd6jOKa35gjxnIqTGc7WpyZj.usda) (2.0 KB)

 ![image](https://us1.discourse-cdn.com/flex016/uploads/aousd/original/1X/8f067c8ceae3990d5211cca9fb51903a9d7ef512.png)

---

<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:** [February 11, 2025, 12:43am UTC](https://forum.aousd.org/t/ordering-of-list-operations-across-arcs/1808/4 "2025-02-11T00:43:23Z")

</div>

@nvmkuruc , I suspect your question has already been answered in the core-spec group, but for visibility here… all of the various cases are explained by the recursive nature of LIVRPS… which listOp you use on a primSpec is relevant only to how that op composes with other similar arcs **in the same layerStack**. As soon as you hop across a reference or other arc, everything defined therein becomes weaker due to the reference nesting/encapsulation. (slight further complexity introduced by “implied inherits”, which is maybe a separate discussion.)
