Skip to content

Load static USD visual shapes by default - #3694

Merged
eric-heiden merged 4 commits into
newton-physics:mainfrom
eric-heiden:eric-heiden/load-static-usd-visuals
Jul 28, 2026
Merged

Load static USD visual shapes by default#3694
eric-heiden merged 4 commits into
newton-physics:mainfrom
eric-heiden:eric-heiden/load-static-usd-visuals

Conversation

@eric-heiden

@eric-heiden eric-heiden commented Jul 27, 2026

Copy link
Copy Markdown
Member

Description

Import visual-only USD geometry outside rigid-body hierarchies as static Newton shapes by default. Add load_static_visual_shapes to ModelBuilder.add_usd() and parse_usd() as an explicit opt-out.

The importer previously loaded ordinary visual geometry only while processing rigid bodies; its standalone visual pass handled Gaussian splats only. As a result, composed static visuals such as /Table/Visuals/TableGeom were omitted. The new path collects supported geometry candidates during the existing deformable scout traversal, avoiding another full instance-proxy walk.

Empty-case paired benchmarks found no measurable regression:

Scene Disabled median Enabled median Difference
500 rigid visual candidates, no static visuals (12 runs) 376.53 ms 376.12 ms -0.11%
Franka robot subtree, no static visuals (6 runs) 2444.27 ms 2438.04 ms -0.26%

Checklist

  • New or existing tests cover these changes
  • The documentation is up to date with these changes
  • CHANGELOG.md has been updated for this user-facing change

Test plan

  • Verified the default-import assertion fails against unmodified origin/main.
  • uv run --extra dev python -m unittest newton.tests.test_import_usd.TestImportSampleAssetsBasic.test_static_visual_shapes_loading_flag -v
  • uv run --extra dev python -m unittest newton.tests.test_import_usd - 280 tests passed.
  • Ran Ruff lint/format checks, typos 1.48.0, the Warp array-syntax checker, and git diff --check directly.
  • uvx pre-commit run -a could not start because the local Git 2.30.0 does not support the git ls-files --deduplicate option required by the installed pre-commit version.

Bug fix

Steps to reproduce:

  1. Create or open a USD stage containing visual geometry outside a rigid-body hierarchy.
  2. Import the stage with ModelBuilder.add_usd().
  3. Observe that the visual prim is absent from path_shape_map on main.

Minimal reproduction:

import newton
from pxr import Usd, UsdGeom

stage = Usd.Stage.CreateInMemory()
UsdGeom.Xform.Define(stage, "/World")
UsdGeom.Cube.Define(stage, "/World/VisualCube")

result = newton.ModelBuilder().add_usd(stage, root_path="/World")
assert "/World/VisualCube" in result["path_shape_map"]

New feature / API change

import newton

builder = newton.ModelBuilder()
builder.add_usd(stage)  # Static visual-only shapes are loaded by default.
builder.add_usd(stage, load_static_visual_shapes=False)  # Explicit opt-out.

Summary by CodeRabbit

  • New Features
    • USD imports now load supported “visual-only” geometry outside rigid-body hierarchies as static shapes by default.
    • Added load_static_visual_shapes to control this behavior independently of other visual loading.
  • Bug Fixes
    • Refined visual-shape loading logic, including more precise traversal/recursion handling and candidate filtering.
  • Documentation
    • Updated USD importer documentation and the Unreleased changelog to reflect the new option.
  • Tests
    • Added tests covering load_static_visual_shapes interactions with static visuals, colliders, and dynamic visuals.

Import visual-only geometry outside rigid-body hierarchies as static shapes by default while retaining an explicit opt-out. Reuse the existing deformable scout so scenes without static visuals do not require another stage traversal.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4113905d-1821-4bd5-8127-52c7f1563f28

📥 Commits

Reviewing files that changed from the base of the PR and between f9873db and 627985a.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • newton/_src/utils/import_usd.py
  • newton/_src/utils/import_usd_deformable_utils.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • newton/_src/utils/import_usd_deformable_utils.py
  • newton/_src/utils/import_usd.py

📝 Walkthrough

Walkthrough

USD import now supports loading visual-only geometry outside rigid-body hierarchies as static shapes by default. Builder and parser options control this behavior, scouting identifies candidates, traversal is bounded for the new pass, and tests cover the option combinations.

Changes

Static USD visual shapes

Layer / File(s) Summary
Importer option and builder wiring
newton/_src/sim/builder.py, newton/_src/utils/import_usd.py
add_usd() and parse_usd() expose and document load_static_visual_shapes, with the builder forwarding it to the importer.
Visual candidate scouting and traversal control
newton/_src/utils/import_usd_deformable_utils.py, newton/_src/utils/import_usd.py
Deformable scouting collects eligible visual candidates, and visual loading supports non-recursive processing for individually handled prims.
Static visual post-pass and validation
newton/_src/utils/import_usd.py, newton/tests/test_import_usd.py, CHANGELOG.md
The importer loads eligible candidates as static shapes, removes the prior specialized scan, and tests loading flags and documented default behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: adenzler-nvidia

Sequence Diagram(s)

sequenceDiagram
  participant ModelBuilder.add_usd
  participant parse_usd
  participant _scout_deformable_prims
  participant _load_visual_shapes_impl
  ModelBuilder.add_usd->>parse_usd: Forward static visual loading option
  parse_usd->>_scout_deformable_prims: Collect eligible static visual candidates
  parse_usd->>_load_visual_shapes_impl: Load candidates without child recursion
  _load_visual_shapes_impl-->>parse_usd: Register static shapes with shape_body == -1
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: static USD visual shapes are now loaded by default.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@eric-heiden
eric-heiden marked this pull request as ready for review July 27, 2026 20:12
@eric-heiden eric-heiden linked an issue Jul 27, 2026 that may be closed by this pull request

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@newton/_src/utils/import_usd_deformable_utils.py`:
- Around line 921-922: Move the collect_static_visuals block that appends to
buckets.static_visuals below the ignore-path guard in the surrounding prim
traversal logic. Ensure ignored prims are excluded before appending, while
non-ignored prims matching _SCOUT_VISUAL_TYPE_NAMES continue to be collected.

In `@newton/_src/utils/import_usd.py`:
- Around line 3291-3301: Update the static-visual loop around
_deformable_prims.static_visuals to skip every prim identified as a CollisionAPI
before calling _load_visual_shapes_impl, using the existing collider/API
detection utilities. Preserve the native collider pass so disabled colliders are
handled there with their collider-specific configuration and visibility policy,
and add a regression test covering a disabled collider.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 97093944-029c-4264-81d0-c405013d1394

📥 Commits

Reviewing files that changed from the base of the PR and between bd44951 and 75839fd.

📒 Files selected for processing (5)
  • changelog.d/+static-usd-visuals-7b9e4c2a.added.md
  • newton/_src/sim/builder.py
  • newton/_src/utils/import_usd.py
  • newton/_src/utils/import_usd_deformable_utils.py
  • newton/tests/test_import_usd.py

Comment thread newton/_src/utils/import_usd_deformable_utils.py Outdated
Comment thread newton/_src/utils/import_usd.py
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread newton/_src/sim/builder.py Outdated
Comment thread newton/_src/utils/import_usd.py
Comment thread newton/_src/utils/import_usd_deformable_utils.py Outdated
Comment thread newton/_src/utils/import_usd.py
Comment thread newton/_src/utils/import_usd_deformable_utils.py Outdated
Make static Gaussian splats honor the static visual loading flag. Keep disabled colliders visual-only and clarify the scout's type and traversal choices.

@jcarius-nv jcarius-nv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three focused follow-ups from the Standards and Newton Fit review, LGTM otherwise. Thank you!

Comment thread CHANGELOG.md Outdated
Comment thread newton/_src/utils/import_usd_deformable_utils.py Outdated
Comment thread newton/_src/sim/builder.py
andrewkaufman
andrewkaufman previously approved these changes Jul 28, 2026
@eric-heiden
eric-heiden added this pull request to the merge queue Jul 28, 2026
Merged via the queue into newton-physics:main with commit e9aabe7 Jul 28, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable USD importer to parse static visuals

3 participants