Asset Structure#
Utility functions for creating Assets following NVIDIA’s Principles of Scalable Asset Structure.
An asset is a named, versioned, and structured container of one or more resources which may include composable OpenUSD layers, textures, volumetric data, and more.
This module aims to codify asset structures that have been proven scalable and have broad import compatibility across a wide range of OpenUSD enabled applications, while guiding and simplifying the development process for new OpenUSD Exporters.
Principles of Scalable Asset Structure#
When developing an asset structure, the following principles can guide toward a scalable structure:
Legibility:
Use descriptive names for layers, scopes, and prims. This might mean using a name like
LargeCardboardBoxorID-2023_5678, depending on the context.The tokens used in this module for files, directories, scopes, and layer names can make things clear and consistent.
Modularity:
The structure should facilitate iterative improvement of reusable content.
The functions in this module use relative paths to allow for asset relocation.
The asset library layer concept allows for the reuse of content within an asset.
Splitting content into different layers per domain (Geometry, Materials, Physics, etc) enables reuse and iteration across workflows.
Performance:
The structure should accelerate content read and write speeds for users and processes.
This could refer to an individual working within an asset or the ability to render millions of preview instances.
This module creates a payload (allowing for deactivation) with extents hints so that the asset can be used in a larger scene.
This module allows the use of text USDA files for lightweight human-readable layers and binary USDC files for heavy data.
Navigability:
The structure should facilitate discovery of elements while retaining flexibility.
The assets should be structured around multiple hierarchical paths (file, directory, prim paths, model hierarchy, etc.).
This module offers functions to generate consistent asset structures.
Basic Structure#
Almost all asset structures require the use of:
While Scopes are easily defined using UsdGeom, it is easy to forget to check if the target location is editable. usdex::core::defineScope prevents this simple mistake.
It is important that assets intended to be placeable within larger assemblies have an Xform or Xformable type. usdex::core::defineXform should be used on the default prim of placeable assets.
References and Payloads can be more complex. The usdex::core::defineReference and usdex::core::definePayload functions provide a simple interface to create them, ensuring to author a relative AssetPath whenever possible (for portability).
Atomic Models#
Atomic models are entirely self contained, have no external dependencies, and are usually Components in the Model Hierarchy.
Because model hierarchy/kind is difficult to maintain manually, two functions are provided to help:
usdex::core::configureComponentHierarchy: Configures a component hierarchy, setting all descendantcomponentstosubcomponentusdex::core::configureAssemblyHierarchy: Configures an assembly hierarchy, setting all authored descendant kinds togroupuntil acomponentis found
The following diagram shows the file, directory, layer, and reference structure of an atomic model:
+---------------------------+ +-----------------------------+
| Asset Layer w/ Interface | | Asset Content Layer |
+---------------------------+ +-----------------------------+
| Flower | +---> Physics.usda |
| { | | | { |
| defaultPrim=/Flower | | | defaultPrim=/Flower |
| } | | | } |
| | | | |
| Xform Flower | | | Xform Flower |
| payloads[ | | | Scope Geometry |
| ./Payload/Contents.usda| | | # physics attrs applied |
| ] | | | | # to prims |
+---------------+-----------+ | | Scope Physics |
| | | Material PhysicsMaterial |
| | +-----------------------------+
| |
| | +-----------------------------+
+---------------v-----------+ | | Asset Content Layer |
| Asset Payload Layer | | +-----------------------------+
+---------------------------+ | +-> Materials.usda |+------------------------+
| Contents.usda | | | | { || Asset Library Layer |
| { | | | | defaultPrim=/Flower |+------------------------+
| defaultPrim=/Flower | | | | } || MaterialsLibrary.usdc |
| sublayers[ | | | | || { |
| ./Physics.usda---------+-+ | | Xform Flower || defaultPrim=/Materials|
| ./Materials.usda-------+---+ | Scope Materials || } |
| ./Geometry.usda--------+--+ | +->Material Clay || |
| } | | | | reference[ || Scope Materials |
| | | | | ./MaterialsLibrary.usdc++-->Material Clay |
| Xform Flower | | | | ] || Material GreenStem |
+---------------------------+ | | | over Geometry || Material PinkPetal |
| | | over Planter { |+------------------------+
| | +----material:binding=Clay |
| | } |
| +-----------------------------+
|
| +-----------------------------+
| | Asset Content Layer |
| +-----------------------------+
+--> Geometry.usda |+------------------------+
| { || Asset Library Layer |
| defaultPrim=/Flower |+------------------------+
| } || GeometryLibrary.usdc |
| || { |
| Xform Flower || defaultPrim=/Geometry|
| Scope Geometry || } |
| Mesh Planter || |
| reference[ || Scope Geometry |
| ./GeometryLibrary.usdc-++-->Mesh Planter |
| ] || Mesh Stem |
| ... || Mesh Petals |
+-----------------------------++------------------------+
Authoring an Atomic Model#
An example sequence for authoring the Flower atomic asset:
Create the primary layer for the asset using
usdex::core::createStage, setting the defaultPrim to/FlowerCreate a relative layer within a Payload subdirectory to hold the content of the asset using
usdex::core::createAssetPayloadAdd a geometry library using
usdex::core::addAssetLibrary(stage, "Geometry")Add planter, stem, and petals meshes to the geometry library
Add a materials library using
usdex::core::addAssetLibrary(stage, "Materials")Add clay, green stem, and pink petals materials to the materials library
Add a geometry content layer using
usdex::core::addAssetContent(stage, "Geometry")Add planter, stem, and petals references that contain xformOps
Add a materials content layer using
usdex::core::addAssetContent(stage, "Materials")Add clay, green stem, and pink petals references and bind them to the geometry
Add the asset interface to the primary layer using
usdex::core::addAssetInterfaceThis creates a payload to the contents within the primary layer, configures asset information, and adds extents hints
Note
These asset structure functions are highly opinionated and implement best practices following NVIDIA’s Principles of Scalable Asset Structure. They provide broad import compatibility across a wide range of OpenUSD enabled applications. However, if you require more flexibility to suit one specific application, renderer, or custom pipeline, these functions may serve you better as a sample implementation rather than something you call directly.
Functions Summary#
- pxr::UsdStageRefPtr usdex::core::addAssetContent(pxr::UsdStagePtr stage, const std::string &name, const std::string &format="usda", const pxr::SdfLayer::FileFormatArguments &fileFormatArgs=pxr::SdfLayer::FileFormatArguments(), bool prependLayer=true, bool createScope=true)
Create a specific Content Layer and add it as a sublayer to the stage's edit target.
- bool usdex::core::addAssetInterface(pxr::UsdStagePtr stage, const pxr::UsdStagePtr source)
Add an Asset Interface to a stage, which payloads a source stage's contents.
- pxr::UsdStageRefPtr usdex::core::addAssetLibrary(pxr::UsdStagePtr stage, const std::string &name, const std::string &format="usdc", const pxr::SdfLayer::FileFormatArguments &fileFormatArgs=pxr::SdfLayer::FileFormatArguments())
Create a Library Layer from which the Content Layers can reference prims.
- bool usdex::core::configureAssemblyHierarchy(pxr::UsdPrim prim)
Configure a prim and its descendants to establish a proper asset assembly hierarchy.
- bool usdex::core::configureComponentHierarchy(pxr::UsdPrim prim)
Configure a prim and its descendants to establish a proper asset component hierarchy.
- pxr::UsdStageRefPtr usdex::core::createAssetPayload(pxr::UsdStagePtr stage, const std::string &format="usda", const pxr::SdfLayer::FileFormatArguments &fileFormatArgs=pxr::SdfLayer::FileFormatArguments())
Create a relative layer within a
getPayloadToken()subdirectory to hold the content of an asset.- pxr::UsdPrim usdex::core::definePayload(pxr::UsdStagePtr stage, const pxr::SdfPath &path, const pxr::UsdPrim &source)
Define a payload to a prim.
- pxr::UsdPrim usdex::core::definePayload(pxr::UsdPrim parent, const std::string &name, const std::string &sourceIdentifier, std::optional< pxr::SdfPath > primPath=std::nullopt)
Define a payload prim as a child of
parentthat references an external USD file.- pxr::UsdPrim usdex::core::definePayload(pxr::UsdStagePtr stage, const pxr::SdfPath &path, const std::string &sourceIdentifier, std::optional< pxr::SdfPath > primPath=std::nullopt)
Define a payload to a prim from a USD file.
- pxr::UsdPrim usdex::core::definePayload(pxr::UsdPrim parent, const pxr::UsdPrim &source, std::optional< std::string_view > name=std::nullopt)
Define a payload to a prim as a child of the
parentprim.- pxr::UsdPrim usdex::core::defineReference(pxr::UsdPrim parent, const std::string &name, const std::string &sourceIdentifier, std::optional< pxr::SdfPath > primPath=std::nullopt)
Define a reference prim as a child of
parentthat references an external USD file.- pxr::UsdPrim usdex::core::defineReference(pxr::UsdStagePtr stage, const pxr::SdfPath &path, const std::string &sourceIdentifier, std::optional< pxr::SdfPath > primPath=std::nullopt)
Define a reference to a prim from a USD file.
- pxr::UsdPrim usdex::core::defineReference(pxr::UsdPrim parent, const pxr::UsdPrim &source, std::optional< std::string_view > name=std::nullopt)
Define a reference to a prim as a child of the
parentprim.- pxr::UsdPrim usdex::core::defineReference(pxr::UsdStagePtr stage, const pxr::SdfPath &path, const pxr::UsdPrim &source)
Define a reference to a prim.
- pxr::UsdGeomScope usdex::core::defineScope(pxr::UsdPrim prim)
Defines a scope from an existing prim.
- pxr::UsdGeomScope usdex::core::defineScope(pxr::UsdStagePtr stage, const pxr::SdfPath &path)
Defines a scope on the stage.
- pxr::UsdGeomScope usdex::core::defineScope(pxr::UsdPrim parent, const std::string &name)
Defines a scope on the stage.
- const pxr::TfToken & usdex::core::getAssetToken()
Get the Asset token.
- const pxr::TfToken & usdex::core::getContentsToken()
Get the token for the Contents layer.
- const pxr::TfToken & usdex::core::getGeometryToken()
Get the token for the Geometry layer and scope.
- const pxr::TfToken & usdex::core::getLibraryToken()
Get the token for the Library layer.
- const pxr::TfToken & usdex::core::getMaterialsToken()
Get the token for the Materials layer and scope.
- const pxr::TfToken & usdex::core::getPayloadToken()
Get the token for the Payload directory.
- const pxr::TfToken & usdex::core::getPhysicsToken()
Get the token for the Physics layer and scope.
- const pxr::TfToken & usdex::core::getTexturesToken()
Get the token for the Textures directory.