Skip to main content

new-validator

Add a new performance-validator rule that wraps a Usd Optimize analysis-mode operation. Use when creating a new validator rule class from scratch.

Source facts

Repository
NVIDIA-Omniverse/usd-optimize
Last source activity
October 1, 2026 at 01:28
Detected SKILL.md language
English
Stars
36
Forks
7

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
new-validator
description
Add a new performance-validator rule that wraps a Usd Optimize analysis-mode operation. Use when creating a new validator rule class from scratch.
allowed-tools
Shell, Read, Edit, Write
metadata
{"author":"NVIDIA Corporation","version":"2.0.0","tags":["validation","performance","authoring"]}
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> <!-- SPDX-License-Identifier: Apache-2.0 --> # new-validator — Add a new performance validator rule Creates a new `usd-validation-nvidia` rule class that wraps a Usd Optimize analysis-mode operation, registers it, tests it, and regenerates the docs. The backing operation must already support analysis mode. If it doesn't, add `executeAnalysisImpl()` to the operation first (see `PLUGINS.md` § Analysis Mode). ## What this skill covers - **How validators work** — the base class, key class variables, and lifecycle. - **Step 1** — create the rule class. - **Step 2** — implement `_CheckStage`. - **Step 3** — add a fix suggestion (optional). - **Step 4** — add user-tunable parameters (optional). - **Step 5** — register the rule. - **Step 6** — add tests. - **Step 7** — build and verify. Companion skills: [`new-operation`](../new-operation/SKILL.md) (create the backing operation), [`run-validators`](../run-validators/SKILL.md) (run the validator and apply fixes). --- ## How validators work All rule classes subclass `BaseUsdOptimizeChecker` from `source/validators/python/usd_optimize/validators/base_usd_optimize_checker.py`. The base class handles running the operation in analysis mode via `CheckStage()`. It calls `_AnalyzeStage()` to execute the operation, then passes the `analysis` payload from the result to `_CheckStage()` — the one method every subclass must implement. Key class variables: | Variable | Required | Purpose | |---|---|---| | `OPERATION_NAME` | Yes | The operation key string (matches the C++ constructor first arg). | | `OPERATION_ARGS` | No | Static `dict` of args forwarded to the operation every run. Defaults to `{}`. | | `PARAMETERS` | No | User-tunable args exposed through Asset Validator's parameter UI. See Step 4. | Look at the existing checkers under `source/validators/python/usd_optimize/validators/` as the primary reference. `empty_leaf_checker.py` is the simplest example; `small_mesh_checker.py` shows `PARAMETERS`; `base_duplicate_geometry_checker.py` shows a shared base class pattern. --- ## Step 1 — Create the rule class Create `source/validators/python/usd_optimize/validators/<snake_case>_checker.py`: ```python # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 from pxr import Usd from usd_validation_nvidia import capabilities, register_requirements from .base_usd_optimize_checker import BaseUsdOptimizeChecker @register_requirements(capabilities.<FamilyRequirements>.<RULE_ID>) class <Name>Checker(BaseUsdOptimizeChecker): """ One-sentence description of what this rule checks. """ OPERATION_NAME: str = "<operation_key>" OPERATION_ARGS: dict = {"argName": value, ...} # omit if no static args needed def _CheckStage(self, usdStage: Usd.Stage, analysis_data: dict): ... ``` `@register_requirements` binds the rule to an Asset Validator capability ID (from `usd_validation_nvidia.capabilities`). Pass `override=True` if overriding an existing base rule for the same capability. ## Step 2 — Implement `_CheckStage` `analysis_data` is the `dict` returned by the operation's analysis mode (the `"analysis"` key from the result). Its schema is specific to each operation — read the operation's `executeAnalysisImpl()` in the C++ source to see what it returns. Call `self._AddWarning()` (most common) or `self._AddFailedCheck()` for each issue. The `at` argument takes a `Usd.Stage` or `Usd.Prim`: ```python def _CheckStage(self, usdStage: Usd.Stage, analysis_data: dict): count = len(analysis_data.get("someKey", [])) if count > 0: self._AddWarning( message=f"Stage contains {count} problematic prims", at=usdStage.GetPrimAtPath("/"), ) ``` To also report individual prim-level issues, iterate the paths and add a separate warning per prim with `at=usdStage.GetPrimAtPath(path)`. ## Step 3 — Add a fix suggestion (optional) Rules that can auto-fix attach a `Suggestion` to the warning. The suggestion's `callable` receives `(usdStage, at_prim)` and applies the fix via `analysis.optimize()`. Use `functools.partial` to bind extra args: ```python from functools import partial from usd_optimize.core import analysis from usd_validation_nvidia import Suggestion @classmethod def _fix_stage(cls, usdStage: Usd.Stage, _: Usd.Prim) -> None: analysis.optimize(usdStage, [analysis.OperationConfig(cls.OPERATION_NAME, args=cls.OPERATION_ARGS)]) def _CheckStage(self, usdStage: Usd.Stage, analysis_data: dict): ... self._AddWarning( message="...", at=usdStage.GetPrimAtPath("/"), suggestion=Suggestion( message="Fix using Usd Optimize", callable=self._fix_stage, ), ) ``` When the fix should use the operation configs derived from the analysis result (rather than static args), use `self.suggested_operations` — it is populated by `_AnalyzeStage` before `_CheckStage` is called. See `small_mesh_checker.py` and `zero_extent_checker.py` for this pattern: ```python suggestion=Suggestion( message="Fix using Usd Optimize", callable=partial(self._fix_stage, operation_configs=self.suggested_operations), ) ``` ## Step 4 — Add user-tunable parameters (optional) Declare `PARAMETERS` to expose per-rule settings in Asset Validator's parameter UI. Each entry maps a display name to a `Parameter` that names the underlying operation arg and its default: ```python from .base_usd_optimize_checker import BaseUsdOptimizeChecker, Parameter, ParameterFromOpArg class MyChecker(BaseUsdOptimizeChecker): PARAMETERS = { "SIZE_THRESHOLD": Parameter(op_arg="threshold", default=0.001, description="Minimum size before a mesh is flagged."), } ``` Use `ParameterFromOpArg` instead of `Parameter` to pull the default and description directly from the operation's argument metadata (avoids duplication): ```python PARAMETERS = { "SIZE_THRESHOLD": ParameterFromOpArg("threshold"), } ``` In `_CheckStage`, read the effective value (with any user override applied) via `self._effective_args()["threshold"]` rather than `OPERATION_ARGS` directly. ## Step 5 — Register the rule In `source/validators/python/usd_optimize/validators/__init__.py`: 1. Add an import at the top: ```python from .<snake_case>_checker import <Name>Checker ``` 2. Add to `_RULE_CATEGORIES`: ```python (<Name>Checker, "Usd:Performance"), # or "Omni:Geometry" ``` Use `"Usd:Performance"` for stage/scene-level conditions; `"Omni:Geometry"` for low-level geometric defects. 3. Add to `__all__`. ## Step 6 — Add tests Add test cases for the new rule to the existing test files in `source/tests/test.python/`: - **`test_checkers.py`** — functional tests using `ValidationTestCaseMixin.assertRule()`. Add a test method that supplies a `.usda` fixture and asserts the expected warnings. Add the required fixtures to the test data directory. - **`test_validator_plugin_entry_point.py`** — no changes needed; it imports from `_RULE_CATEGORIES` and covers all registered rules automatically. - **`test_checker_parameters.py`** — add a test only if the rule declares `PARAMETERS` and has non-trivial parameter logic to verify. ## Step 7 — Build and verify ```bash ./repo.sh build ./repo.sh test -s python ./repo.sh docs_gen --autogen_only ``` After `docs_gen`, the rule appears in [`docs/performance-validators.rst`](../../../docs/performance-validators.rst). Verify the rule is registered: ```python import usd_validation_nvidia # import first from usd_optimize.validators import register_all rules = register_all() # register_all() renames each rule to UsdOptimize<Name>Checker before returning it, # so assert against the registered name, not the class name as written. assert any(r.__name__ == "UsdOptimize<Name>Checker" for r in rules) ```
View on GitHub