Traversing a Stage
VERIFIED ON USD VERSION 21.08
Setup Python
This tutorial walks through the API that traverses over the composed prims on a given stage. This is the typical pattern for implementing imaging clients, USD importers to other DCC applications, etc. We will use the layers that we produced in the Referencing Layers example. You will need the referenced layer, HelloWorld.usda, and the referencing layer, RefExample.usda, which are in the USD/extras/usd/tutorials/traversingStage folder. Please copy that folder to a working directory and make its contents writable.
- Open RefExample.usda in usdview and bring up the interpreter by hitting i or the Window --> Interpreter menu item.
-
The interpreter opens with a number of local variables that you can use to introspect the composed scenegraph, and Usd.Stage.Traverse() will perform a depth-first traversal over its prims.
>>> [x for x in usdviewApi.stage.Traverse()]
for our stage returns
[Usd.Prim(</refSphere>), Usd.Prim(</refSphere/world>), Usd.Prim(</refSphere2>), Usd.Prim(</refSphere2/world>)]
and you can filter the list comprehension as you would any other generator in Python:
>>> [x for x in usdviewApi.stage.Traverse() if UsdGeom.Sphere(x)]
returns
[Usd.Prim(</refSphere/world>), Usd.Prim(</refSphere2/world>)]
-
For more involved traversals, the Usd.PrimRange() exposes pre- and post-order prim visitations.
>>> treeItr = iter(Usd.PrimRange.PreAndPostVisit(usdviewApi.stage.GetPseudoRoot())) >>> for x in treeItr: print x, treeItr.IsPostVisit()
Returns
Usd.Prim(</>) False Usd.Prim(</refSphere>) False Usd.Prim(</refSphere/world>) False Usd.Prim(</refSphere/world>) True Usd.Prim(</refSphere>) True Usd.Prim(</refSphere2>) False Usd.Prim(</refSphere2/world>) False Usd.Prim(</refSphere2/world>) True Usd.Prim(</refSphere2>) True Usd.Prim(</>) True
-
Usd.PrimRange also makes prim-flag predicates available. In fact, Usd.Stage.Traverse() is really a convenience method that performs pre-order visitations on all the prims in the composed scenegraph that are active, defined, loaded, and concrete.
In Referencing Layers, we touched upon what it means for a prim to be defined, i.e., it is backed by a def rather than an over. The concepts of being loaded and concrete respectively correlate to payloads (composition boundaries across which scene description does not get composed unless explicitly requested) and classes (abstract prims whose opinions apply to all prims which inherit from them). We will discuss these operators more in depth in a future tutorial, but can take a look at activation/deactivation semantics via usdview here.
Select refSphere2 in the Prim Name pane on the left, and hit Edit --> Deactivate in the menubar. The result should look like this.
You can inspect the contents of the session layer in the interpreter,>>> print usdviewApi.stage.GetSessionLayer().ExportToString()
to see the authored deactivation opinion.
#usda 1.0 over "refSphere2" ( active = false ) { }
The session layer holds transient opinions on the stage that a user would not want to commit and thereby affect downstream departments.
Now Traverse() will not visit refSphere2 or any of its namespace children, and the GL renderer does not draw it in the viewport.
>>> [x for x in usdviewApi.stage.Traverse()]
should return
[Usd.Prim(</refSphere>), Usd.Prim(</refSphere/world>)]
While we can still see refSphere2 as an inactive prim on the stage, its children no longer have any presence in the composed scenegraph. We can use TraverseAll() to get a tree iterator with no predicates applied to verify this.>>> [x for x in usdviewApi.stage.TraverseAll()]
should return
[Usd.Prim(</refSphere>), Usd.Prim(</refSphere/world>), Usd.Prim(</refSphere2>)]