API Reference

grill.usd

Helpers for USD workflows which do not know anything about the pipeline.

grill.usd.common_paths(paths: Iterable[Path]) list[Path]

For the given paths, get those which are the common parents.

grill.usd.edit_context(
prim: Prim,
/,
query_filter: Filter,
predicate: Callable[[CompositionArc], bool],
) EditContext
grill.usd.edit_context(arc: Payload, /, prim: Prim) EditContext
grill.usd.edit_context(arc: Reference, /, prim: Prim) EditContext
grill.usd.edit_context(arc: Inherits, /, path: Path, layer: Layer) EditContext
grill.usd.edit_context(arc: Specializes, /, path: Path, layer: Layer) EditContext
grill.usd.edit_context(variant_set: VariantSet, /, layer: Layer) EditContext

Get an EditTarget for the first arc in the Prims’s composition for which the given predicate returns True.

Overloaded implementations allow for a direct search targetting Payload, References, Specializes, Inherits and VariantSet.

This allows for “chained” context switching of edit targets while working with the same USD API objects.

Tip

You can try the below code snippet on USDView (or any other USD DCC application) Just swap the main = Usd.Stage.CreateInMemory() assignment for a stage on the viewport, e.g, for USDView:

>>> main = usdviewApi.stage

Then paste the rest of the code as-is:

https://user-images.githubusercontent.com/8294116/133999486-b13e811a-91f4-4d8c-92d9-44c1f81b82d4.gif
Example:
>>> from pxr import Usd, UsdGeom, Sdf
>>> main = Usd.Stage.CreateInMemory()
>>> # Jump between 3 different layer stacks adding variants to the same set
>>> # main [variant blue] -> reference [variant green] -> payload [variant red]
>>> referenced = Usd.Stage.CreateInMemory()
>>> referenced.SetDefaultPrim(referenced.DefinePrim("/Referenced"))
>>> reference = Sdf.Reference(referenced.GetRootLayer().identifier)
>>>
>>> payloaded = Usd.Stage.CreateInMemory()
>>> payloaded.SetDefaultPrim(payloaded.DefinePrim("/Payloaded"))
>>> payload = Sdf.Payload(payloaded.GetRootLayer().identifier)
>>>
>>> top = main.DefinePrim("/Top")
>>> top.GetReferences().AddReference(reference)
True
>>> import grill.usd as gusd
>>> with gusd.edit_context(reference, top):
...     top.GetPayloads().AddPayload(payload)
...     with gusd.edit_context(payload, top):
...         geom = UsdGeom.Sphere.Define(main, top.GetPath().AppendPath("inner/child"))
...         color = geom.GetDisplayColorAttr()
...         color_set = geom.GetPrim().GetVariantSets().AddVariantSet("color")
...         color_set.AddVariant("from_payload")
...         color_set.SetVariantSelection("from_payload")
...         with gusd.edit_context(color_set, payloaded.GetRootLayer()):  # color_set.GetVariantEditContext() would fail here
...             color.Set([(1,0,0)])
...         color_set.ClearVariantSelection()
...     color_set.AddVariant("from_reference")
...     color_set.SetVariantSelection("from_reference")
...     with gusd.edit_context(color_set, referenced.GetRootLayer()):
...         color.Set([(0,1,0)])
...     color_set.ClearVariantSelection()
...
True
>>> color_set.AddVariant("from_top")
>>> color_set.SetVariantSelection("from_top")
>>> with color_set.GetVariantEditContext():
...     color.Set([(0,0,1)])
...
>>> color_set.ClearVariantSelection()
True
>>> for each in main, referenced, payloaded:
...     print(each.GetRootLayer().ExportToString())
...
#usda 1.0
def "Top" (
    prepend references = @anon:0000019B6BE92A70:tmp.usda@
)
{
    over "inner"
    {
        over "child" (
            prepend variantSets = "color"
        )
        {
            variantSet "color" = {
                "from_top" {
                    color3f[] primvars:displayColor = [(0, 0, 1)]
                }
            }
        }
    }
}
#usda 1.0
(
    defaultPrim = "Referenced"
)
def "Referenced" (
    prepend payload = @anon:0000019B6BE93270:tmp.usda@
)
{
    over "inner"
    {
        over "child" (
            prepend variantSets = "color"
        )
        {
            variantSet "color" = {
                "from_reference" {
                    color3f[] primvars:displayColor = [(0, 1, 0)]
                }
            }
        }
    }
}
#usda 1.0
(
    defaultPrim = "Payloaded"
)
def "Payloaded"
{
    def "inner"
    {
        def Sphere "child" (
            prepend variantSets = "color"
        )
        {
            variantSet "color" = {
                "from_payload" {
                    color3f[] primvars:displayColor = [(1, 0, 0)]
                }
            }
        }
    }
}
grill.usd.iprims(
stage: Stage,
root_paths: Iterable[Path] = (),
prune_predicate: Callable[[Prim], bool] | None = None,
traverse_predicate: _Term | _PrimFlagsConjunction = Usd.PrimDefaultPredicate,
) Iterator[Prim]

Convenience function that creates an iterator useful for common Stage Traversal.

Without keyword arguments, this is the same as calling UsdStage::Traverse(), so use that instead when neither root_paths nor prune_predicate are provided.

A PrimRage with the provided traverse_predicate is created for each common Path in root_paths, and PruneChildren is called whenever prune_predicate returns True for a traversed Prim.

grill.usd.iter_recursive_instances(prims: Iterable[Prim]) Iterator[Prim]

For the given prims, recursively iterate over all instances from their prototypes.

grill.cook

Important

In order to use this module, ensure the extra feature grill[create] was installed. Alternatively, the module will be enabled by installing grill-names in the environment. Refer to the install instructions for more details.

Inspecting, authoring and editing foundational tools for the pipeline.

grill.cook.Repository

contextvars.ContextVar for the global asset repository location.

Its value must always be set to a pathlib.Path.

Attention

By default, no value has been set. Ensure to set it before performing any creation operation.

Example:
>>> Repository.get()  # not set
Traceback (most recent call last):
  File "<input>", line 1, in <module>
LookupError: <ContextVar name='Repository' at 0x00000207F0A12B88>
>>> import tempfile
>>> from pathlib import Path
>>> Repository.set(Path(tempfile.mkdtemp()))
<Token var=<ContextVar name='Repository' at 0x00000213A46FF900> at 0x00000213C6A9F0C0>
>>> Repository.get()
WindowsPath('C:/Users/CHRIST~1/AppData/Local/Temp/tmp767wqaya')
grill.cook.asset_identifier(path: Path | str)

Since identifiers from relative paths can become absolute when opening existing assets, this function ensures to return the value expected to be authored in layers.

grill.cook.create_many(taxon: Prim, names: Iterable[str], labels: Iterable[str] = ()) list[Prim]

Create a new taxon member for each of the provided names.

When creating hundreds or thousands of members, this provides a considerable performance improvement over create_unit().

The new members will be created as prims on the given taxon’s stage.

grill.cook.create_unit(taxon: Prim, name: str, label: str = '') Prim

Create a unit member of the given taxon, with an optional display label.

The new member will be created as a prim on the given taxon’s stage.

grill.cook.define_taxon(
stage: Stage,
name: str,
*,
references: tuple[Prim] = (),
id_fields: Mapping[str, str] = mappingproxy({}),
) Prim

Define a new taxon group for asset taxonomy and return it.

If an existing taxon with the provided name already exists in the stage, it is used.

The new taxon can extend from existing taxa via the references argument.

Optional field=value items can be provided for identification purposes through id_fields.

grill.cook.fetch_stage(
identifier: str | UsdAsset,
context: ResolverContext | None = None,
load: InitialLoadSet = Usd.Stage.LoadAll,
) Stage

Retrieve the stage whose root layer matches the given identifier.

If the layer does not exist, it is created in the repository.

Attention

identifier must be a valid grill.names.UsdAsset name.

grill.cook.filter_taxa(
prims: Iterable[Prim],
taxon: Prim | str,
*taxa: Prim,
) Iterator[Prim]

From the given prims, yield those that are part of the given taxa.

grill.cook.itaxa(stage: Stage) Iterator[Prim]

For the given stage, iterate existing taxa under the taxonomy hierarchy.

grill.cook.spawn_many(parent: Prim, child: Prim, paths: list[Path], labels: list[str] = ()) list[Prim]

Spawn many instances of a prim unit as descendants of another.

  • Both parent and child must be existing units in the catalogue.

  • paths can be relative or absolute. If absolute, they must include parent’s path as a prefix.

  • A valid Model Hierarchy is preserved by:

    1. Turning parent into an assembly if child is a Model.

    2. Ensuring intermediate prims between parent and spawned children are also models.

    3. Setting explicit instanceable. on spawned children that are components.

Spawned prims and ancestors are defined.

grill.cook.spawn_unit(parent: Prim, child: Prim, path: Path = Sdf.Path.emptyPath, label: str = '') Prim

Spawn a unit prim as a descendant of another.

  • Both parent and child must be existing units in the catalogue.

  • If path is not provided, the name of child will be used.

  • A valid Model Hierarchy is preserved by:

    1. Turning parent into an Assembly.

    2. Ensuring intermediate prims between parent and child are also Model.

    3. Setting explicit Instanceable. on spawned children that are components.

grill.cook.taxonomy_context(stage: Stage) EditContext

Get an edit context where edits will target this stage’s taxonomy layer.

Attention

If a valid taxonomy layer is not found on the layer stack, one is added to the stage.

grill.cook.taxonomy_graph(prims: Prim, url_id_prefix: str) DiGraph
grill.cook.taxonomy_graph(stage: Stage, url_id_prefix: str) DiGraph

Get the hierarchical taxonomy representation of existing prims.

grill.cook.unit_asset(prim: Prim) Layer

Get the asset layer that acts as the ‘entry point’ for the given prim.

grill.cook.unit_context(prim: Prim) EditContext

Get an edit context where edits will target this prim’s unit root layer.

class grill.cook.UsdAsset(*args, sep='-', **kwargs)

Specialized grill.names.CGAssetFile name object for USD asset resources.

This is the currency for USD asset identifiers in the pipeline.

Examples:
>>> asset_id = UsdAsset.get_default()
>>> asset_id
UsdAsset("demo-3d-abc-entity-rnd-main-atom-lead-base-whole.1.usda")
>>> asset_id.suffix = 'usdc'
>>> asset_id.version = 42
>>> asset_id
UsdAsset("demo-3d-abc-entity-rnd-main-atom-lead-base-whole.42.usdc")
>>> asset_id.suffix = 'abc'
Traceback (most recent call last):
...
ValueError: Can't set invalid name 'demo-3d-abc-entity-rnd-main-atom-lead-base-whole.42.abc' on UsdAsset("demo-3d-abc-entity-rnd-main-atom-lead-base-whole.42.usdc"). Valid convention is: '{code}-{media}-{kingdom}-{cluster}-{area}-{stream}-{item}-{step}-{variant}-{part}.{pipe}.{suffix}' with pattern: '^(?P<code>...(?P<suffix>sdf|usd|usda|usdc|usdz))$'

See also

grill.names.CGAsset for a description of available fields, naming.Name for an overview of the core API.

Note

This class is defined on the grill.names module but is exposed here for convenience.

Hint

For quick prototyping, grill.names.UsdAsset.get_anonymous() can be used to get temporary but valid grill identifiers.