From e3b963b4ee622d2d07ae5f60ce9c5684f0d4966f Mon Sep 17 00:00:00 2001 From: Jerry Gamache Date: Mon, 29 Aug 2022 12:22:19 -0400 Subject: [PATCH] Resync prim path on connection changed Fixes #2013 A connection changed notification implies a shader rebuild, which should force a rescan of cached data for the affected material/light/camera. In the cas of a material, this will also force a rescan of the dependent geometries, which is exactly what is needed to fix the refresh issue. --- pxr/usdImaging/usdImaging/delegate.cpp | 28 +++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/pxr/usdImaging/usdImaging/delegate.cpp b/pxr/usdImaging/usdImaging/delegate.cpp index 6ce62ce57c..2ef23ee62b 100644 --- a/pxr/usdImaging/usdImaging/delegate.cpp +++ b/pxr/usdImaging/usdImaging/delegate.cpp @@ -1120,13 +1120,31 @@ UsdImagingDelegate::_OnUsdObjectsChanged( using PathRange = UsdNotice::ObjectsChanged::PathRange; + // If there was a connection changed inside a shade graph, this also + // requires dumping all cached data since we need to rebuild the shader. + auto isConnectionChanged = [](auto const& i){ + for (const auto& entry : i.base()->second) { + if (entry->flags.didChangeAttributeConnection) { + return true; + } + } + return false; + }; + // These paths are subtree-roots representing entire subtrees that may have // changed. In this case, we must dump all cached data below these points // and repopulate those trees. const PathRange pathsToResync = notice.GetResyncedPaths(); - _usdPathsToResync.insert(_usdPathsToResync.end(), - pathsToResync.begin(), pathsToResync.end()); - + for (PathRange::const_iterator itResync = pathsToResync.begin(); + itResync != pathsToResync.end(); ++itResync) { + if (itResync->IsPrimPropertyPath() && isConnectionChanged(itResync)) { + // Resync the prim path instead of the property path: + _usdPathsToResync.emplace_back(itResync->GetPrimPath()); + } else { + _usdPathsToResync.emplace_back(*itResync); + } + } + // These paths represent objects which have been modified in a // non-structural way, for example setting a value. These paths may be paths // to prims or properties, in which case we should sparsely invalidate @@ -1147,6 +1165,10 @@ UsdImagingDelegate::_OnUsdObjectsChanged( } } else if (it->IsPropertyPath()) { _usdPathsToUpdate.emplace(*it, TfTokenVector()); + if (isConnectionChanged(it)) { + // Resync the prim path as well: + _usdPathsToResync.emplace_back(it->GetPrimPath()); + } } }