diff --git a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp index 121fdf1a24..a46bc4d6b0 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp +++ b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp @@ -665,6 +665,13 @@ void HdVP2BasisCurves::Sync( if (HdChangeTracker::IsVisibilityDirty(*dirtyBits, id)) { _sharedData.visible = delegate->GetVisible(id); + + // Invisible rprims don't get calls to Sync or _PropagateDirtyBits while + // they are invisible. This means that when a prim goes from visible to + // invisible that we must update every repr, because if we switch reprs while + // invisible we'll get no chance to update! + if (!_sharedData.visible) + _MakeOtherReprRenderItemsInvisible(delegate, reprToken); } if (*dirtyBits @@ -1681,6 +1688,39 @@ void HdVP2BasisCurves::_InitRepr(TfToken const& reprToken, HdDirtyBits* dirtyBit } } +/*! \brief Hide all of the repr objects for this Rprim except the named repr. + Repr objects are created to support specific reprName tokens, and contain a list of + HdVP2DrawItems and corresponding RenderItems. +*/ +void HdVP2BasisCurves::_MakeOtherReprRenderItemsInvisible( + HdSceneDelegate* sceneDelegate, + const TfToken& reprToken) +{ + for (const std::pair& pair : _reprs) { + if (pair.first != reprToken) { + // For each relevant draw item, update dirty buffer sources. + const HdReprSharedPtr& repr = pair.second; + const auto& items = repr->GetDrawItems(); + +#if HD_API_VERSION < 35 + for (HdDrawItem* item : items) { + if (HdVP2DrawItem* drawItem = static_cast(item)) { +#else + for (const HdRepr::DrawItemUniquePtr& item : items) { + if (HdVP2DrawItem* const drawItem = static_cast(item.get())) { +#endif + for (auto& renderItemData : drawItem->GetRenderItems()) { + _delegate->GetVP2ResourceRegistry().EnqueueCommit([&renderItemData]() { + renderItemData._enabled = false; + renderItemData._renderItem->enable(false); + }); + } + } + } + } + } +} + /*! \brief Update the named repr object for this Rprim. Repr objects are created to support specific reprName tokens, and contain a list of diff --git a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h index 41ea6e8568..a2d1bf815a 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h @@ -129,6 +129,7 @@ class HdVP2BasisCurves final : public HdBasisCurves private: void _UpdateRepr(HdSceneDelegate* sceneDelegate, TfToken const& reprToken); + void _MakeOtherReprRenderItemsInvisible(HdSceneDelegate*, const TfToken&); void _CommitMVertexBuffer(MHWRender::MVertexBuffer* const, void*) const; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp b/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp index 42fcc2af4f..f571800235 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp +++ b/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp @@ -1042,6 +1042,13 @@ void HdVP2Mesh::Sync( if (HdChangeTracker::IsVisibilityDirty(*dirtyBits, id)) { _sharedData.visible = delegate->GetVisible(id); + + // Invisible rprims don't get calls to Sync or _PropagateDirtyBits while + // they are invisible. This means that when a prim goes from visible to + // invisible that we must update every repr, because if we switch reprs while + // invisible we'll get no chance to update! + if (!_sharedData.visible) + _MakeOtherReprRenderItemsInvisible(delegate, reprToken); } if (*dirtyBits @@ -1474,6 +1481,41 @@ void HdVP2Mesh::_CreateSmoothHullRenderItems(HdVP2DrawItem& drawItem) TF_VERIFY(numFacesWithoutRenderItem == 0); } +/*! \brief Hide all of the repr objects for this Rprim except the named repr. + + Repr objects are created to support specific reprName tokens, and contain a list of + HdVP2DrawItems and corresponding RenderItems. +*/ +void HdVP2Mesh::_MakeOtherReprRenderItemsInvisible( + HdSceneDelegate* sceneDelegate, + const TfToken& reprToken) +{ + for (const std::pair& pair : _reprs) { + if (pair.first != reprToken) { + // For each relevant draw item, update dirty buffer sources. + _MeshReprConfig::DescArray reprDescs = _GetReprDesc(pair.first); + int drawItemIndex = 0; + for (size_t descIdx = 0; descIdx < reprDescs.size(); ++descIdx, drawItemIndex++) { + const HdMeshReprDesc& desc = reprDescs[descIdx]; + if (desc.geomStyle == HdMeshGeomStyleInvalid) { + continue; + } + auto* drawItem + = static_cast(pair.second->GetDrawItem(drawItemIndex)); + if (!drawItem) + continue; + + for (auto& renderItemData : drawItem->GetRenderItems()) { + _delegate->GetVP2ResourceRegistry().EnqueueCommit([&renderItemData]() { + renderItemData._enabled = false; + renderItemData._renderItem->enable(false); + }); + } + } + } + } +} + /*! \brief Update the named repr object for this Rprim. Repr objects are created to support specific reprName tokens, and contain a list of diff --git a/lib/mayaUsd/render/vp2RenderDelegate/mesh.h b/lib/mayaUsd/render/vp2RenderDelegate/mesh.h index b2ee7edb9a..087c9d83e7 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/mesh.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/mesh.h @@ -125,6 +125,7 @@ class HdVP2Mesh final : public HdMesh void _InitRepr(const TfToken&, HdDirtyBits*) override; void _UpdateRepr(HdSceneDelegate*, const TfToken&); + void _MakeOtherReprRenderItemsInvisible(HdSceneDelegate*, const TfToken&); void _CommitMVertexBuffer(MHWRender::MVertexBuffer* const, void*) const;