name: Fix Redundant Dirty Notices
overview: "HdDependencyForwardingSceneIndex emits redundant PrimsDirtied notices for the same prim: one combined entry (extent, primvars/normals, primvars/points) plus three separate per-locator entries. Fix by consolidating the output so downstream receives a single notice per prim."
todos: []
isProject: false
Fix Redundant Dirty Notifications in HdDependencyForwardingSceneIndex
Summary
During blend-shape or skinned animation, the Scene Index Notice Logger shows 4 dirtied notices for the same mesh prim instead of 1:
extent, primvars/normals, primvars/points (combined)
extent
primvars/normals
primvars/points
Downstream consumers may process the mesh multiple times per frame, adding unnecessary cost especially when each primvars/points notice triggers a full mesh rebuild.
Root Cause
File: AdskUsd/pxr/imaging/hd/dependencyForwardingSceneIndex.cpp
In _PrimsDirtied (lines 105-126):
for (const DirtiedPrimEntry &entry : entries) {
for (const HdDataSourceLocator &sourceLocator : entry.dirtyLocators) {
_PrimDirtied(entry.primPath, sourceLocator, &visited, &affectedEntries);
}
}
if (affectedEntries.empty()) {
_SendPrimsDirtied(entries);
} else {
affectedEntries.insert(affectedEntries.begin(), entries.begin(), entries.end());
_SendPrimsDirty(affectedEntries);
}
- The loop calls
_PrimDirtied for each locator; _PrimDirtied appends {primPath, singleLocator} to affectedEntries
- When
affectedEntries is non-empty, the output merges the original entries (multi-locator) with affectedEntries (per-locator)
- Result: same prim appears with both the combined locator set and each individual locator
Fix Strategy
Consolidate the output so each prim appears at most once with a merged locator set:
- When building
affectedEntries from _PrimDirtied, merge locators by prim path instead of emitting one entry per locator
- Or: do not prepend the original
entries when they are already represented in affectedEntries (avoid duplicate coverage for the same prim)
- Or: after the loop, merge entries that share the same
primPath into a single entry with the union of their locators
The fix must preserve dependency-forwarding behavior: when prim A depends on prim B, dirtying B must still propagate to A. The redundancy is only in emitting both {path, {a,b,c}} and {path, a}, {path, b}, {path, c} for the same prim.
Implementation Approach
-
Merge entries by prim path before sending: iterate over affectedEntries + original entries, group by primPath, and union locators. Emit one DirtiedPrimEntry per prim with the combined locator set.
-
Alternative: In the else branch, do not insert the original entries at the beginning. Instead, merge each original entry's locators into the corresponding affectedEntries for that prim (or add the prim if not yet in affectedEntries). Then send only the merged result.
-
Verify: Use the Scene Index Notice Logger to confirm a single dirtied notice per prim per frame during blend-shape playback.
Files to Modify
| File |
Change |
| AdskUsd/pxr/imaging/hd/dependencyForwardingSceneIndex.cpp |
Consolidate _PrimsDirtied output to one entry per prim with merged locators |
name: Fix Redundant Dirty Notices
overview: "HdDependencyForwardingSceneIndex emits redundant PrimsDirtied notices for the same prim: one combined entry (extent, primvars/normals, primvars/points) plus three separate per-locator entries. Fix by consolidating the output so downstream receives a single notice per prim."
todos: []
isProject: false
Fix Redundant Dirty Notifications in HdDependencyForwardingSceneIndex
Summary
During blend-shape or skinned animation, the Scene Index Notice Logger shows 4 dirtied notices for the same mesh prim instead of 1:
extent, primvars/normals, primvars/points(combined)extentprimvars/normalsprimvars/pointsDownstream consumers may process the mesh multiple times per frame, adding unnecessary cost especially when each
primvars/pointsnotice triggers a full mesh rebuild.Root Cause
File: AdskUsd/pxr/imaging/hd/dependencyForwardingSceneIndex.cpp
In
_PrimsDirtied(lines 105-126):_PrimDirtiedfor each locator;_PrimDirtiedappends{primPath, singleLocator}toaffectedEntriesaffectedEntriesis non-empty, the output merges the originalentries(multi-locator) withaffectedEntries(per-locator)Fix Strategy
Consolidate the output so each prim appears at most once with a merged locator set:
affectedEntriesfrom_PrimDirtied, merge locators by prim path instead of emitting one entry per locatorentrieswhen they are already represented inaffectedEntries(avoid duplicate coverage for the same prim)primPathinto a single entry with the union of their locatorsThe fix must preserve dependency-forwarding behavior: when prim A depends on prim B, dirtying B must still propagate to A. The redundancy is only in emitting both
{path, {a,b,c}}and{path, a},{path, b},{path, c}for the same prim.Implementation Approach
Merge entries by prim path before sending: iterate over
affectedEntries+ originalentries, group byprimPath, and union locators. Emit oneDirtiedPrimEntryper prim with the combined locator set.Alternative: In the
elsebranch, do not insert the originalentriesat the beginning. Instead, merge each original entry's locators into the correspondingaffectedEntriesfor that prim (or add the prim if not yet inaffectedEntries). Then send only the merged result.Verify: Use the Scene Index Notice Logger to confirm a single dirtied notice per prim per frame during blend-shape playback.
Files to Modify
_PrimsDirtiedoutput to one entry per prim with merged locators