Quick Start#

usd-profiles-nvidia lets pipeline teams describe a validation contract as authored documentation, generate Python objects from that same source, and use those objects with usd-validation-nvidia.

This guide creates a small profile package for a factory pipeline. The profile validates assets against the built-in Minimal Placeable Visual feature and adds one custom requirement: every boundable prim must fit inside a configured bounding-box size.

Install#

Install the profile tooling and validation engine:

pip install usd-profiles-nvidia usd-validation-nvidia

Add the Sphinx extra when building profile documentation:

pip install usd-profiles-nvidia[sphinx]

Create a Specs Tree#

Create a specs/ directory in your profile package:

specs/
  capabilities/
    factory_geometry/
      capability-factory_geometry.md
      requirements/
        factory-boundable-size.md
  features/
    factory_bounds.toml
  profiles/
    profiles.toml

Author the Requirement#

The requirement describes the policy and declares the values that the rule can read:

# factory-boundable-size

| Code          | GEOMETRY.001             |
|---------------|--------------------------|
| Version       | 1.0.0                    |
| Compatibility | {compatibility}`OpenUSD` |
| Validator     | FactoryBoundsChecker     |
| Tags          | {tag}`correctness`       |

## Summary

Factory assets must fit within the configured bounding-box dimensions.

## Description

The validator computes each boundable prim's world-space bounding box and compares its size to the configured factory
limits. The default values below describe the placement envelope for one factory line in meters.

## Parameters

| Parameter    | Type  | Default Value |
|--------------|-------|---------------|
| MAX_X_METERS | float | 6.0           |
| MAX_Y_METERS | float | 6.0           |
| MAX_Z_METERS | float | 4.0           |

## Why is it required?

- Prevents oversized assets from blocking automated placement.
- Catches unit-scale mistakes before assets reach assembly scenes.
- Keeps factory layout validation aligned with the physical production cell.

## Examples

### Invalid: oversized fixture

```usd
#usda 1.0
(
    metersPerUnit = 1
)

def Cube "OversizedFixture"
{
    double size = 8
}
```

### Valid: bounded fixture

```usd
#usda 1.0
(
    metersPerUnit = 1
)

def Cube "Fixture"
{
    double size = 2
}
```

## How to comply

- Confirm `metersPerUnit` matches the source asset's authored unit scale.
- Split large equipment into separately placed assets when the factory workflow expects modular props.
- Reduce unused geometry, collision, or visualization extents that inflate the computed bounding box.

The Default Value column is the profile package’s default configuration. At runtime, users can override those values with --parameter or ValidationEngine.add_parameter().

Add a Capability#

Capabilities group related requirements. This example creates a factory geometry capability:

# Factory Geometry

## Overview

Factory geometry requirements describe the dimensional constraints needed to place assets into automated assembly
scenes.

## Requirements

```{requirements-table}
```

Add a Feature#

The feature depends on the built-in Minimal Placeable Visual feature and contributes the factory bounding-box requirement:

id = "factory_bounds"
version = "1.0.0"
dependencies = [
    "com.nvidia.usd.minimal_placeable_visual@1.0.0",
]
requirements = [
    "GEOMETRY.001@1.0.0",
]

Use the fully-qualified com.nvidia.usd.minimal_placeable_visual@1.0.0 entry in dependencies so the generated package keeps that reference external. The validation engine resolves it from the built-in usd-validation-nvidia registrations.

Add a Profile#

The profile only needs to select the customer feature. That feature brings in Minimal Placeable Visual through dependencies:

[Factory-Asset]
"1.0.0" = {features = [
    {"factory_bounds" = {version = "1.0.0"}},
]}

Generate Python#

Generate Python objects from the authored specs:

python -m usd_profiles_nvidia.codegen \
  --docs-root specs \
  --destination-dir generated \
  --package-name factory_asset_profiles \
  --reverse-domain com.example.factory

The reverse domain qualifies local identifiers. For example, GEOMETRY.001 becomes com.example.factory.GEOMETRY.001, while com.nvidia.usd.minimal_placeable_visual remains an external feature reference.

Bind the Requirement to a Rule#

Register the generated requirement, feature, and profile from a usd_validation_nvidia plugin:

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
import factory_asset_profiles
from pxr import Usd, UsdGeom
from usd_validation_nvidia import (
    BaseRuleChecker,
    ParameterMapping,
    register_features,
    register_profiles,
    register_requirements,
    register_rule,
    unregister_features,
    unregister_profiles,
    unregister_requirements,
    unregister_rule,
)

FACTORY_BOUNDABLE_SIZE = factory_asset_profiles.Requirements.GEOMETRY_001


class FactoryBoundsChecker(BaseRuleChecker):
    """Validate boundable prim sizes against factory limits."""

    def __init__(self, parameters: ParameterMapping | None = None) -> None:
        super().__init__(parameters=parameters)
        self._meters_per_unit: float = 1.0
        self._bbox_cache: UsdGeom.BBoxCache | None = None

    def CheckStage(self, stage: Usd.Stage) -> None:
        self._meters_per_unit = UsdGeom.GetStageMetersPerUnit(stage)
        self._bbox_cache = UsdGeom.BBoxCache(
            Usd.TimeCode.Default(),
            [UsdGeom.Tokens.default_],
        )

    def CheckPrim(self, prim: Usd.Prim) -> None:
        if not UsdGeom.Boundable(prim):
            return

        if self._bbox_cache is None:
            self._bbox_cache = UsdGeom.BBoxCache(
                Usd.TimeCode.Default(),
                [UsdGeom.Tokens.default_],
            )

        bounds = self._bbox_cache.ComputeWorldBound(prim).ComputeAlignedRange()
        if bounds.IsEmpty():
            return

        size_meters = bounds.GetSize() * self._meters_per_unit
        limits = (
            float(self.parameters["MAX_X_METERS"].assigned_value),
            float(self.parameters["MAX_Y_METERS"].assigned_value),
            float(self.parameters["MAX_Z_METERS"].assigned_value),
        )

        if all(size_meters[axis] <= limits[axis] for axis in range(3)):
            return

        self._AddFailedCheck(
            message=f"Boundable prim {prim.GetPath()} exceeds factory bounds {limits}.",
            at=prim,
            requirement=FACTORY_BOUNDABLE_SIZE,
        )

    def ResetCaches(self) -> None:
        self._bbox_cache = None


class Plugin:
    def on_startup(self) -> None:
        register_features(factory_asset_profiles.Features)
        register_profiles(factory_asset_profiles.Profiles)
        register_requirements(FACTORY_BOUNDABLE_SIZE)(FactoryBoundsChecker)
        register_rule("Factory")(FactoryBoundsChecker)

    def on_shutdown(self) -> None:
        unregister_rule(FactoryBoundsChecker)
        unregister_requirements(FactoryBoundsChecker)
        unregister_profiles(factory_asset_profiles.Profiles)
        unregister_features(factory_asset_profiles.Features)

Add the plugin entry point to your package:

[project.entry-points."usd_validation_nvidia"]
factory_validation = "factory_validation:Plugin"

Validate Assets#

Install the generated profile package and plugin into the same Python environment as usd-validation-nvidia, then select the profile:

nvidia_usd_validate \
  --profile com.example.factory.Factory-Asset \
  path/to/factory_prop.usda

Override the default bounding-box limits for a specific factory line:

nvidia_usd_validate \
  --profile com.example.factory.Factory-Asset \
  --parameter MAX_X_METERS=4.0 \
  --parameter MAX_Y_METERS=3.0 \
  --parameter MAX_Z_METERS=2.5 \
  path/to/factory_prop.usda