Skip to content

Fix stale Gaussian splat handles after set_visible_worlds() - #4084

Open
aneangel wants to merge 1 commit into
newton-physics:mainfrom
aneangel:aneangel/fix-4020-stale-gaussian-splat-handle
Open

Fix stale Gaussian splat handles after set_visible_worlds()#4084
aneangel wants to merge 1 commit into
newton-physics:mainfrom
aneangel:aneangel/fix-4020-stale-gaussian-splat-handle

Conversation

@aneangel

@aneangel aneangel commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Description

set_visible_worlds() left stale, still-visible Gaussian splat handles
behind in ViewerViser (and any other backend that tracks handles by
name).

Gaussian shape names were generated using len(_gaussian_instances) as
a sequential counter. That counter resets to zero every time
set_visible_worlds() rebuilds the list, so world N's shape would steal
world 0's old backend name. World N's original name became an orphan
in _scene_handles — its handle was never visited again, so it was
never hidden or removed. The result was a frozen duplicate rendering at
the shape's last known position alongside the live copy.

Two changes fix this:

  1. Stable names — use the global shape index s (its position in
    the model's fixed shape array) as the name suffix instead of
    len(_gaussian_instances). Each shape's name is now invariant across
    set_visible_worlds() calls.
  2. Cleanup — after repopulating _gaussian_instances, hide handles
    for any Gaussian name that is no longer in the active set.

Closes #4020

Checklist

  • New or existing tests cover these changes
  • The documentation is up to date with these changes
  • For user-facing changes, a fragment has been added by following the
    changelog fragment instructions

Test plan

uv run --extra dev newton/tests/test_viewer_log_shapes.py
uv run --extra dev newton/tests/test_viewer_visible_worlds.py
uv run --extra dev newton/tests/test_viewer_geometry_batching.py

All pass with no failures.

Bug fix

Steps to reproduce (without this PR):

  1. Build a model with two worlds, each containing one Gaussian shape.
  2. Render one frame with both worlds visible.
  3. Call set_visible_worlds([1]) and render another frame.
  4. World 1 now renders twice: once live at its current position, and
    once as a frozen duplicate stuck at its prior position.

Minimal reproduction: see the script in issue #4020.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed stale Gaussian visualization handles remaining visible after changing the set of visible worlds.
    • Ensured Gaussian shape identifiers remain stable across visibility updates.
    • Improved cleanup when worlds are hidden or removed from the current view.
  • Documentation

    • Added a changelog entry describing the visibility-handling fix.

Gaussian shape names were derived from len(_gaussian_instances), a
counter that reset to zero every time set_visible_worlds() rebuilt the
list. This caused world N's shape to steal world 0's old backend name,
leaving world N's original handle orphaned in _scene_handles as a
frozen, still-visible duplicate.

Two changes fix this:
- Use the stable global shape index s as the name suffix instead of
  the sequential counter, so each shape's name is invariant across
  visibility changes.
- After repopulating _gaussian_instances, hide handles for any Gaussian
  name that is no longer in the active set.

Closes newton-physics#4020
@aneangel
aneangel requested a deployment to external-pr-approval August 28, 2026 18:17 — with GitHub Actions Waiting
@aneangel
aneangel requested a deployment to external-pr-approval August 28, 2026 18:17 — with GitHub Actions Waiting
@coderabbitai

coderabbitai Bot commented Aug 28, 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: 44ee3a34-c16d-4168-aa6f-903e9119ec81

📥 Commits

Reviewing files that changed from the base of the PR and between bdf01ba and fb9ac5f.

📒 Files selected for processing (2)
  • changelog/4020.fixed.md
  • newton/_src/viewer/viewer.py

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

set_visible_worlds() now preserves Gaussian instance names across repopulation and hides handles for Gaussian instances that are no longer visible. A changelog entry documents the fix.

Changes

Gaussian visibility fix

Layer / File(s) Summary
Stable naming and stale-handle cleanup
newton/_src/viewer/viewer.py, changelog/4020.fixed.md
_populate_shapes derives Gaussian names from stable shape indices. set_visible_worlds snapshots previous instances and hides handles absent from the newly populated set. The changelog records the fix.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🔵 Low · up to fb9ac

The change fixes stale Gaussian renders by preserving stable shape identities and hiding handles that are no longer active, but an interrupted visibility rebuild could still leave obsolete handles visible and unreachable for cleanup; the PR is mergeable with explicit owner awareness of this bounded failure-path risk.

Suggested reviewers: nvtw

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #4020 by assigning stable Gaussian shape names and hiding handles for Gaussian instances that are no longer active after visibility changes.
Out of Scope Changes check ✅ Passed The code and changelog changes directly support the stale Gaussian handle fix described in issue #4020. No unrelated changes are present.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: fixing stale Gaussian splat handles after set_visible_worlds().
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ 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.

@aneangel
aneangel marked this pull request as ready for review August 28, 2026 20:35
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.

[BUG] set_visible_worlds() leaves a stale, still-visible Gaussian splat handle behind

1 participant