From ef120b26bc4cb39bd58901cafed13dfcb65b93e3 Mon Sep 17 00:00:00 2001 From: tcauchois Date: Thu, 23 Sep 2021 16:26:10 -0700 Subject: [PATCH] [usdImaging] Fix GprimAdapter::_AddRprim material resolution order to be consistent with other functions. In GetMaterialId (on instancers and gprims) and GprimAdapter::UpdateForTime, we consider the local material binding to take precedence over the instancer material binding. This is consistent with the basic USD rules, where more local material assignments take precedence. However, this was flipped in _AddRprim, which would preferentially take the instancer material binding. For many scene structures, this wasn't causing issues, since only one of the material bindings would be non-empty; or they would point to the same path, which is sketchy but worked in practice. However, this specifically fixes a bug concerning scenes where a point instancer prototype is marked as instanceable, and the material bound to the prototype is inside the instance; in this case, the old code would have a disagreement about whether the material was named /World/path/to/material or /Prototype_N/path/to/material, and so the relationship in hydra would be broken. Fixes #1626 (Internal change: 2190000) --- pxr/usdImaging/usdImaging/gprimAdapter.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pxr/usdImaging/usdImaging/gprimAdapter.cpp b/pxr/usdImaging/usdImaging/gprimAdapter.cpp index 9856c706ab..f1643b9c8c 100644 --- a/pxr/usdImaging/usdImaging/gprimAdapter.cpp +++ b/pxr/usdImaging/usdImaging/gprimAdapter.cpp @@ -146,9 +146,11 @@ UsdImagingGprimAdapter::_AddRprim(TfToken const& primType, index->AddDependency(cachePath, usdPrim); } - // Allow instancer context to override the material binding. - SdfPath resolvedUsdMaterialPath = instancerContext ? - instancerContext->instancerMaterialUsdPath : materialUsdPath; + // If there's no local material path, fall back to the instancer material. + SdfPath resolvedUsdMaterialPath = materialUsdPath; + if (materialUsdPath.IsEmpty() && instancerContext != nullptr) { + resolvedUsdMaterialPath = instancerContext->instancerMaterialUsdPath; + } UsdPrim materialPrim = usdPrim.GetStage()->GetPrimAtPath(resolvedUsdMaterialPath);