Skip to content

Commit

Permalink
[usdImaging] Improve processing of primvar property changes.
Browse files Browse the repository at this point in the history
- Remove previous limitation (stemming from Storm) on having to resync a prim if a primvar was added/removed or had its interpolation updated.
- Update/Add helper methods in UsdImagingPrimAdapter to figure out what changed about the primvar and treat value changes differently from descriptor changes (as seen by Hydra backends) and update the primvar descriptors entry in the value cache in the case of reomval.

Note that the dirty bit used for authored primvars is currently the same (DirtyPrimvar) for both value and descriptor changes. We expect this to change in the near future with the introduction of a new dirty bit for descriptor changes.

Fixes #1078

(Internal change: 2049164)
  • Loading branch information
rajabala authored and pixar-oss committed Mar 12, 2020
1 parent c718018 commit 42cc5ee
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 112 deletions.
41 changes: 24 additions & 17 deletions pxr/usdImaging/usdImaging/basisCurvesAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,27 +230,34 @@ UsdImagingBasisCurvesAdapter::ProcessPropertyChange(UsdPrim const& prim,
SdfPath const& cachePath,
TfToken const& propertyName)
{
// Even though points is treated as a primvar, it is special and is always
// treated as a vertex primvar.
if (propertyName == UsdGeomTokens->points)
return HdChangeTracker::DirtyPoints;

if (propertyName == UsdGeomTokens->widths ||
propertyName == UsdImagingTokens->primvarsWidths) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, HdTokens->widths)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyWidths;
}
// Handle attributes that are treated as "built-in" primvars.
if (propertyName == UsdGeomTokens->widths) {
UsdGeomBasisCurves curves(prim);
return UsdImagingPrimAdapter::_ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdTokens->widths,
_UsdToHdInterpolation(curves.GetWidthsInterpolation()),
HdChangeTracker::DirtyWidths);

} else if (propertyName == UsdGeomTokens->normals) {
UsdGeomBasisCurves curves(prim);
return UsdImagingPrimAdapter::_ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdTokens->normals,
_UsdToHdInterpolation(curves.GetNormalsInterpolation()),
HdChangeTracker::DirtyNormals);
}

if (propertyName == UsdGeomTokens->normals ||
propertyName == UsdImagingTokens->primvarsNormals) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, HdTokens->normals)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyNormals;
}
// Handle prefixed primvars that use special dirty bits.
else if (propertyName == UsdImagingTokens->primvarsWidths) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdChangeTracker::DirtyWidths);

} else if (propertyName == UsdImagingTokens->primvarsNormals) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdChangeTracker::DirtyNormals);
}

// Allow base class to handle change processing.
Expand Down
31 changes: 11 additions & 20 deletions pxr/usdImaging/usdImaging/gprimAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,15 @@ UsdImagingGprimAdapter::UpdateForTime(UsdPrim const& prim,
instancerContext) const
{
UsdImagingValueCache* valueCache = _GetValueCache();
HdPrimvarDescriptorVector& primvars = valueCache->GetPrimvars(cachePath);
HdPrimvarDescriptorVector& vPrimvars = valueCache->GetPrimvars(cachePath);

if (requestedBits & HdChangeTracker::DirtyPoints) {

valueCache->GetPoints(cachePath) = GetPoints(prim, cachePath, time);

// Expose points as a primvar.
_MergePrimvar(
&primvars,
&vPrimvars,
HdTokens->points,
HdInterpolationVertex,
HdPrimvarRoleTokens->point);
Expand All @@ -294,7 +294,7 @@ UsdImagingGprimAdapter::UpdateForTime(UsdPrim const& prim,
pointBased.GetVelocitiesAttr().Get(&velocities, time)) {
// Expose velocities as a primvar.
_MergePrimvar(
&primvars,
&vPrimvars,
HdTokens->velocities,
HdInterpolationVertex,
HdPrimvarRoleTokens->vector);
Expand All @@ -310,7 +310,7 @@ UsdImagingGprimAdapter::UpdateForTime(UsdPrim const& prim,
pointBased.GetAccelerationsAttr().Get(&accelerations, time)) {
// Expose accelerations as a primvar.
_MergePrimvar(
&primvars,
&vPrimvars,
HdTokens->accelerations,
HdInterpolationVertex,
HdPrimvarRoleTokens->vector);
Expand Down Expand Up @@ -344,7 +344,7 @@ UsdImagingGprimAdapter::UpdateForTime(UsdPrim const& prim,
if (GetColor(prim, time, &colorInterp, &color)) {
valueCache->GetColor(cachePath) = color;
_MergePrimvar(
&primvars,
&vPrimvars,
HdTokens->displayColor,
_UsdToHdInterpolation(colorInterp),
HdPrimvarRoleTokens->color);
Expand All @@ -361,7 +361,7 @@ UsdImagingGprimAdapter::UpdateForTime(UsdPrim const& prim,
if (GetOpacity(prim, time, &opacityInterp, &opacity)) {
valueCache->GetOpacity(cachePath) = opacity;
_MergePrimvar(
&primvars,
&vPrimvars,
HdTokens->displayOpacity,
_UsdToHdInterpolation(opacityInterp));
} else {
Expand Down Expand Up @@ -459,20 +459,11 @@ UsdImagingGprimAdapter::ProcessPropertyChange(UsdPrim const& prim,
return HdChangeTracker::DirtyMaterialId;
}

// Is the property a primvar?
static std::string primvarsNS = "primvars:";
if (TfStringStartsWith(propertyName.GetString(), primvarsNS)) {
TfToken primvarName = TfToken(
propertyName.GetString().substr(primvarsNS.size()));

if (!_IsBuiltinPrimvar(primvarName)) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, primvarName)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyPrimvar;
}
}
// Note: This doesn't handle "built-in" attributes that are treated as
// primvars. That responsibility falls on the child adapter.
if (UsdImagingPrimAdapter::_HasPrimvarsPrefix(propertyName)) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName);
}

return HdChangeTracker::AllDirty;
Expand Down
14 changes: 3 additions & 11 deletions pxr/usdImaging/usdImaging/instanceAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1283,17 +1283,9 @@ UsdImagingInstanceAdapter::ProcessPropertyChange(UsdPrim const& prim,
return HdChangeTracker::DirtyInstanceIndex;
}

// Is the property a primvar?
static std::string primvarsNS = "primvars:";
if (TfStringStartsWith(propertyName.GetString(), primvarsNS)) {
TfToken primvarName = TfToken(
propertyName.GetString().substr(primvarsNS.size()));
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, primvarName)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyPrimvar;
}
if (UsdImagingPrimAdapter::_HasPrimvarsPrefix(propertyName)) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName);
}

// For other property changes, blast everything. This will trigger a
Expand Down
20 changes: 12 additions & 8 deletions pxr/usdImaging/usdImaging/meshAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,18 @@ UsdImagingMeshAdapter::ProcessPropertyChange(UsdPrim const& prim,
// (Note that a change in subdivision scheme means we need to re-track
// the variability of the normals...)

if (propertyName == UsdGeomTokens->normals ||
propertyName == UsdImagingTokens->primvarsNormals) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, HdTokens->normals)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyNormals;
}
// Handle attributes that are treated as "built-in" primvars.
if (propertyName == UsdGeomTokens->normals) {
UsdGeomMesh mesh(prim);
return UsdImagingPrimAdapter::_ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdTokens->normals,
_UsdToHdInterpolation(mesh.GetNormalsInterpolation()),
HdChangeTracker::DirtyNormals);
}
// Handle prefixed primvars that use special dirty bits.
else if (propertyName == UsdImagingTokens->primvarsNormals) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdChangeTracker::DirtyNormals);
}

// Allow base class to handle change processing.
Expand Down
26 changes: 9 additions & 17 deletions pxr/usdImaging/usdImaging/pointInstancerAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,12 +822,9 @@ UsdImagingPointInstancerAdapter::ProcessPropertyChange(UsdPrim const& prim,
primvarName = _tokens->scale;
}

if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, primvarName, false)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyPrimvar;
}
return _ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, primvarName,
HdInterpolationInstance);
}

if (propertyName == UsdGeomTokens->protoIndices ||
Expand All @@ -836,24 +833,19 @@ UsdImagingPointInstancerAdapter::ProcessPropertyChange(UsdPrim const& prim,
}

// Is the property a primvar?
static std::string primvarsNS = "primvars:";
if (TfStringStartsWith(propertyName.GetString(), primvarsNS)) {

if (UsdImagingPrimAdapter::_HasPrimvarsPrefix(propertyName)) {
// Ignore local constant/uniform primvars.
UsdGeomPrimvar pv = UsdGeomPrimvarsAPI(prim).GetPrimvar(propertyName);
if (pv && (pv.GetInterpolation() == UsdGeomTokens->constant ||
pv.GetInterpolation() == UsdGeomTokens->uniform)) {
return HdChangeTracker::Clean;
}

TfToken primvarName = TfToken(
propertyName.GetString().substr(primvarsNS.size()));
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, primvarName, false)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyPrimvar;
}

return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName,
/*valueChangeDirtyBit*/HdChangeTracker::DirtyPrimvar,
/*inherited=*/false);
}

// XXX: Treat transform & visibility changes as re-sync, until we untangle
Expand Down
39 changes: 22 additions & 17 deletions pxr/usdImaging/usdImaging/pointsAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,24 +218,29 @@ UsdImagingPointsAdapter::ProcessPropertyChange(UsdPrim const& prim,
if (propertyName == UsdGeomTokens->points)
return HdChangeTracker::DirtyPoints;

if (propertyName == UsdGeomTokens->widths ||
propertyName == UsdImagingTokens->primvarsWidths) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, HdTokens->widths)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyWidths;
}
// Handle attributes that are treated as "built-in" primvars.
if (propertyName == UsdGeomTokens->widths) {
UsdGeomPoints points(prim);
return UsdImagingPrimAdapter::_ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdTokens->widths,
_UsdToHdInterpolation(points.GetWidthsInterpolation()),
HdChangeTracker::DirtyWidths);

} else if (propertyName == UsdGeomTokens->normals) {
UsdGeomPoints points(prim);
return UsdImagingPrimAdapter::_ProcessNonPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdTokens->normals,
_UsdToHdInterpolation(points.GetNormalsInterpolation()),
HdChangeTracker::DirtyNormals);
}

if (propertyName == UsdGeomTokens->normals ||
propertyName == UsdImagingTokens->primvarsNormals) {
if (_PrimvarChangeRequiresResync(
prim, cachePath, propertyName, HdTokens->normals)) {
return HdChangeTracker::AllDirty;
} else {
return HdChangeTracker::DirtyNormals;
}
// Handle prefixed primvars that use special dirty bits.
else if (propertyName == UsdImagingTokens->primvarsWidths) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdChangeTracker::DirtyWidths);

} else if (propertyName == UsdImagingTokens->primvarsNormals) {
return UsdImagingPrimAdapter::_ProcessPrefixedPrimvarPropertyChange(
prim, cachePath, propertyName, HdChangeTracker::DirtyNormals);
}

// Allow base class to handle change processing.
Expand Down
Loading

0 comments on commit 42cc5ee

Please sign in to comment.