From ab5fa061f9bbffe21573581c799c77b09211c816 Mon Sep 17 00:00:00 2001 From: David Lanier Date: Fri, 12 Jan 2024 16:29:55 +0100 Subject: [PATCH 01/25] HYDRA-691 : Move mayaUsd code for manging stages inside mayHydra --- build.py | 2 +- doc/build.md | 8 + .../API/fvpDataProducerSceneIndexInterface.h | 13 +- .../API/fvpFilteringSceneIndexClient.h | 4 +- .../fvpDataProducerSceneIndexInterfaceImp.cpp | 60 +++- .../fvpDataProducerSceneIndexInterfaceImp.h | 28 +- ...ataProducerSceneIndexDataAbstractFactory.h | 7 + .../fvpDataProducerSceneIndexDataBase.cpp | 94 ++++-- .../fvpDataProducerSceneIndexDataBase.h | 43 ++- ...ormationAndSceneIndicesPerViewportData.cpp | 3 +- .../fvpDataProducerSceneIndexExample.cpp | 3 +- lib/flowViewport/CMakeLists.txt | 1 + lib/mayaHydra/hydraExtensions/CMakeLists.txt | 107 +++++-- .../hydraExtensions/sceneIndex/CMakeLists.txt | 2 + ...ayaHydraMayaDataProducerSceneIndexData.cpp | 16 +- .../mayaHydraMayaDataProducerSceneIndexData.h | 9 +- ...aProducerSceneIndexDataConcreteFactory.cpp | 6 + ...ataProducerSceneIndexDataConcreteFactory.h | 6 + .../mayaHydraMayaUsdProxyShapeSceneIndex.cpp | 134 +++++++++ .../mayaHydraMayaUsdProxyShapeSceneIndex.h | 111 ++++++++ .../sceneIndex/registration.cpp | 267 +++++++++--------- .../hydraExtensions/sceneIndex/registration.h | 2 - .../mayaPlugin/plugRegistryHelper.cpp | 4 - lib/mayaHydra/mayaPlugin/plugin.cpp | 7 - lib/mayaHydra/mayaPlugin/renderOverride.cpp | 30 +- lib/mayaHydra/ufeExtensions/CMakeLists.txt | 17 +- lib/mayaHydra/ufeExtensions/Global.cpp | 29 +- lib/mayaHydra/ufeExtensions/Global.h | 5 +- test/lib/CMakeLists.txt | 86 ------ test/lib/mayaUsd/render/CMakeLists.txt | 5 - 30 files changed, 758 insertions(+), 351 deletions(-) create mode 100644 lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp create mode 100644 lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h diff --git a/build.py b/build.py index 2181ce9f27..0f2c96f6d6 100755 --- a/build.py +++ b/build.py @@ -556,7 +556,7 @@ def Package(context): help="Directory where Maya is installed.") parser.add_argument("--mayausd-location", type=str, - help="Directory where MayaUsd is installed.") + help="Directory where mayaUSD.mod file is.") parser.add_argument("--pxrusd-location", type=str, help="Directory where Pixar USD is installed.") diff --git a/doc/build.md b/doc/build.md index ebea19b063..69bb294fcd 100644 --- a/doc/build.md +++ b/doc/build.md @@ -80,6 +80,14 @@ There are four arguments that must be passed to the script: | --devkit-location | directory where Maya devkit is installed. | | workspace_location | directory where the project use as a workspace to build and install plugin/libraries | +Optional arguments are : +| Flags | Description | +|-------------------- |---------------------------------------------------------------------------------------------------- | +| --mayausd-location | directory where the mayaUSD.mod file is. By providing this, you will enable more features for | +| | usd stages when using an hydra render delegate, such as : hide/delete the stage when the proxy shape| +| | node is hidden/deleted, or applying a transform on the proxy shape node will apply it on the stage. | + + ``` Linux: ➜ maya-hydra python build.py --maya-location /usr/autodesk/maya2024 --pxrusd-location /usr/local/USD-Release --devkit-location /usr/local/devkitBase /usr/local/workspace diff --git a/lib/flowViewport/API/fvpDataProducerSceneIndexInterface.h b/lib/flowViewport/API/fvpDataProducerSceneIndexInterface.h index 420a924847..660b0f06f7 100644 --- a/lib/flowViewport/API/fvpDataProducerSceneIndexInterface.h +++ b/lib/flowViewport/API/fvpDataProducerSceneIndexInterface.h @@ -49,7 +49,10 @@ namespace FVP_NS_DEF * * @param[in] customDataProducerSceneIndex is the custom scene index to add. * - * @param[in] dccNode is a MObject* for Maya, if you provide the pointer value, then we automatically track some events such as transform + * @param[in, out] inoutPreFix is the prefix you want to add to your data producer scene index primitives, it may be modified by this function if you provide a dccnode. + * If you don't want any prefix, pass SdfPath::AbsoluteRootPath() to this parameter. + * + * @param[in] dccNode is a MObject* from a DAG node for Maya, if you provide the pointer value, then we automatically track some events such as transform * or visibility updated and we hide automatically the primitives from the data producer scene index. * If it is a nullptr, we won't do anything if the node's attributes changes. * Basically, this is a way for you to set the DCC node as a parent node for all your primitives from the scene index. @@ -62,19 +65,18 @@ namespace FVP_NS_DEF * This is only used when hydraViewportId is set to DataProducerSceneIndexInterface::allViewports, meaning you want to add this scene index to all viewports * that are using these renderers. * To apply to multiple renderers, use a separator such as ",". E.g : "GL, Arnold". We are actually looking for the render delegate's name in this string. - * Set this parameter to DataProducerSceneIndexInterface::allRenderers to add your scene index to all viewports whatever their renderer is. + * Set this parameter to FvpViewportAPITokens->allRenderers to add your scene index to all viewports whatever their renderer is. * * @param[in] customDataProducerSceneIndexRootPathForInsertion is the root path for insertion used as a second parameter of HdRenderIndex::InsertSceneIndex method. * e.g : renderIndex.InsertSceneIndex(customDataProducerSceneIndex, customDataProducerSceneIndexRootPathForInsertion); * * @return true if the operation succeeded, false otherwise. - * */ virtual bool addDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, + PXR_NS::SdfPath& inoutPreFix, void* dccNode = nullptr, const std::string& hydraViewportId = PXR_NS::FvpViewportAPITokens->allViewports, - const std::string& rendererNames = PXR_NS::FvpViewportAPITokens->allRenderers, - const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion = PXR_NS::SdfPath::AbsoluteRootPath() + const std::string& rendererNames = PXR_NS::FvpViewportAPITokens->allRenderers ) = 0; /** @@ -86,7 +88,6 @@ namespace FVP_NS_DEF * * @param[in] hydraViewportId is the hydra viewport string identifier to which customDataProducerSceneIndex was associated to or DataProducerSceneIndexInterface::allViewports * if it was applied to all viewports. - */ virtual void removeViewportDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, const std::string& hydraViewportId = PXR_NS::FvpViewportAPITokens->allViewports diff --git a/lib/flowViewport/API/fvpFilteringSceneIndexClient.h b/lib/flowViewport/API/fvpFilteringSceneIndexClient.h index 222059036b..efb987b0ba 100644 --- a/lib/flowViewport/API/fvpFilteringSceneIndexClient.h +++ b/lib/flowViewport/API/fvpFilteringSceneIndexClient.h @@ -58,7 +58,7 @@ namespace FVP_NS_DEF * @param[in] rendererNames is the names of the renderers you want this client to be associated to. * If there are several, separate them with for example a coma, like "GL, Arnold", we actually look for the renderer name in this string. * If you want your client to work on any renderer please use FvpViewportAPITokens->allRenderers. - * @param[in] dccNode is a MObject* for Maya, if you provide the pointer value, then we automatically track some events such as visibility changed, + * @param[in] dccNode is a MObject* DAG node for Maya, if you provide the pointer value, then we automatically track some events such as visibility changed, * node deleted/undeleted and we remove/add automatically your filtering scene indices from the viewport. Meaning if the maya node is visible your filtering * scene indices are applied to the scene, if the node is not visible (or deleted) your filtering scene indices are removed from the scene. * If it is a nullptr, your filtering scene indices will stay applied to the viewport(s) until you remove them. @@ -145,7 +145,7 @@ namespace FVP_NS_DEF */ const std::string _rendererNames = PXR_NS::FvpViewportAPITokens->allRenderers; - /**_dccNode is a MObject* for Maya, if you provide the pointer value, then we automatically track some events such as visibility changed, + /**_dccNode is a MObject* DAG node for Maya, if you provide the pointer value, then we automatically track some events such as visibility changed, * node deleted/undeleted and we remove/add automatically your filtering scene indices from the viewport. Meaning if the maya node is visible your filtering * scene indices are applied to the scene, if the node is not visible (or deleted) your filtering scene indices are removed from the scene. * If it is a nullptr, your filtering scene indices will stay applied to the viewport(s) until you remove them. diff --git a/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.cpp b/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.cpp index f1453a1861..9407d691e0 100644 --- a/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.cpp +++ b/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.cpp @@ -52,17 +52,44 @@ DataProducerSceneIndexInterfaceImp& DataProducerSceneIndexInterfaceImp::get() return theInterface; } +//Specific internal function for Usd Stages +PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr DataProducerSceneIndexInterfaceImp::addUsdStageSceneIndex(UsdImagingCreateSceneIndicesInfo& createInfo, + HdSceneIndexBaseRefPtr& finalSceneIndex, + UsdImagingStageSceneIndexRefPtr& stageSceneIndex, + SdfPath& inoutPrefix, + void* dccNode) +{ + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = + _CreateDataProducerSceneIndexDataForUsdStage(createInfo, finalSceneIndex, stageSceneIndex, inoutPrefix, dccNode); + if (nullptr == dataProducerSceneIndexData){ + return nullptr; + } + + inoutPrefix = dataProducerSceneIndexData->GetPrefix(); + + return dataProducerSceneIndexData; +} + +bool DataProducerSceneIndexInterfaceImp::addUsdStageDataProducerSceneIndexDataBaseToAllViewports(PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSceneIndexData){ + //Apply this maya usd scene index to all viewports + return _AddDataProducerSceneIndexToAllViewports(dataProducerSceneIndexData); +} + bool DataProducerSceneIndexInterfaceImp::addDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, + PXR_NS::SdfPath& inoutPrefix, void* dccNode /*= nullptr*/, const std::string& hydraViewportId /*= allViewports*/, - const std::string& rendererNames /*= allRenderers*/, - const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion /*= PXR_NS::SdfPath::AbsoluteRootPath()*/) + const std::string& rendererNames /*= allRenderers*/ + ) { PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = - _CreateDataProducerSceneIndexData(customDataProducerSceneIndex, rendererNames, customDataProducerSceneIndexRootPathForInsertion, dccNode); + _CreateDataProducerSceneIndexData(customDataProducerSceneIndex, rendererNames, inoutPrefix, dccNode); if (nullptr == dataProducerSceneIndexData){ return false; } + + inoutPrefix = dataProducerSceneIndexData->GetPrefix(); + //PXR_NS::FvpViewportAPITokens->allViewports == hydraViewportId means the user wants customDataProducerSceneIndex to be applied in all viewports. if (PXR_NS::FvpViewportAPITokens->allViewports == hydraViewportId){ //Apply this data producer scene index to all viewports @@ -163,9 +190,24 @@ bool DataProducerSceneIndexInterfaceImp::_AddDataProducerSceneIndexToAllViewport return true; } +PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr DataProducerSceneIndexInterfaceImp::_CreateDataProducerSceneIndexDataForUsdStage( + PXR_NS::UsdImagingCreateSceneIndicesInfo& createInfo, HdSceneIndexBaseRefPtr& finalSceneIndex, UsdImagingStageSceneIndexRefPtr& stageSceneIndex, const SdfPath& prefix, void* dccNode) +{ + TF_AXIOM(sceneIndexDataFactory); + + if (! sceneIndexDataFactory){ + TF_CODING_ERROR("sceneIndexDataFactory is a nullptr, it should have been provided by a call to GetDataProducerSceneIndexInterfaceImp()->SetSceneIndexDataFactory"); + return nullptr; + } + + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage params(createInfo, finalSceneIndex, stageSceneIndex, prefix, dccNode); + return sceneIndexDataFactory->createDataProducerSceneIndexDataBaseForUsdStage(params); +} + + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr DataProducerSceneIndexInterfaceImp::_CreateDataProducerSceneIndexData(const HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, const std::string& rendererNames, - const SdfPath& customDataProducerSceneIndexRootPathForInsertion, + const SdfPath& prefix, void* dccNode) { TF_AXIOM(sceneIndexDataFactory); @@ -175,7 +217,7 @@ PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr DataProducerSceneIndexI return nullptr; } - const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters params(customDataProducerSceneIndex, rendererNames, customDataProducerSceneIndexRootPathForInsertion, dccNode); + const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters params(customDataProducerSceneIndex, rendererNames, prefix, dccNode); return sceneIndexDataFactory->createDataProducerSceneIndexDataBase(params); } @@ -212,7 +254,7 @@ void DataProducerSceneIndexInterfaceImp::_AddDataProducerSceneIndexToThisViewpor //Add it to the merging scene index if the render inex proxy is present, it may happen that it will be set later auto renderIndexProxy = viewportInformationAndSceneIndicesPerViewportData->GetRenderIndexProxy(); if (renderIndexProxy && dataProducerSceneIndexData && dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain()){ - renderIndexProxy->InsertSceneIndex(dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain(), dataProducerSceneIndexData->GetCustomDataProducerSceneIndexRootPathForInsertion()); + renderIndexProxy->InsertSceneIndex(dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain(), SdfPath::AbsoluteRootPath()); } } @@ -230,4 +272,10 @@ void DataProducerSceneIndexInterfaceImp::setSceneIndexDataFactory(DataProducerSc sceneIndexDataFactory = &factory; } +void DataProducerSceneIndexInterfaceImp::ClearDataProducerSceneIndicesThatApplyToAllViewports() +{ + std::lock_guard lockDataProducerSceneIndicesDataPerViewport(dataProducerSceneIndicesThatApplyToAllViewports_mutex); + dataProducerSceneIndicesThatApplyToAllViewports.clear(); +} + } //End of namespace FVP_NS_DEF diff --git a/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.h b/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.h index ee7b6bd407..c92ca4a2e9 100644 --- a/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.h +++ b/lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.h @@ -29,6 +29,10 @@ //Std Headers #include +//Hydra headers +#include + + namespace FVP_NS_DEF { class ViewportInformationAndSceneIndicesPerViewportData; @@ -43,16 +47,29 @@ class DataProducerSceneIndexInterfaceImp : public DataProducerSceneIndexInterfac ///Interface accessor static FVP_API DataProducerSceneIndexInterfaceImp& get(); + ///Specific internal function for Usd Stages + FVP_API PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr addUsdStageSceneIndex( PXR_NS::UsdImagingCreateSceneIndicesInfo& createInfo, + PXR_NS::HdSceneIndexBaseRefPtr& finalSceneIndex, + PXR_NS::UsdImagingStageSceneIndexRefPtr& stageSceneIndex, + PXR_NS::SdfPath& inoutPreFix, + void* dccNode); + + ///Specific internal function for Usd Stages + FVP_API bool addUsdStageDataProducerSceneIndexDataBaseToAllViewports(PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSceneIndexData); + ///From FVP_NS_DEF::DataProducerSceneIndexInterface bool addDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, + PXR_NS::SdfPath& inoutPreFix, void* dccNode = nullptr, const std::string& hydraViewportId = PXR_NS::FvpViewportAPITokens->allViewports, - const std::string& rendererNames = PXR_NS::FvpViewportAPITokens->allRenderers, - const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion = PXR_NS::SdfPath::AbsoluteRootPath() + const std::string& rendererNames = PXR_NS::FvpViewportAPITokens->allRenderers )override; void removeViewportDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, const std::string& hydraViewportId = PXR_NS::FvpViewportAPITokens->allViewports)override; + + FVP_API void ClearDataProducerSceneIndicesThatApplyToAllViewports(); + //Called by flow viewport ///hydraViewportSceneIndexAdded is called when a new hydra viewport is created by the ViewportInformationAndSceneIndicesPerViewportDataManager, it's not a callback. void hydraViewportSceneIndexAdded(const InformationInterface::ViewportInformation& viewportInfo); @@ -68,8 +85,13 @@ class DataProducerSceneIndexInterfaceImp : public DataProducerSceneIndexInterfac PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr _CreateDataProducerSceneIndexData( const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, const std::string& rendererNames, - const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion, + const PXR_NS::SdfPath& prefix, void* dccNode); + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr _CreateDataProducerSceneIndexDataForUsdStage(PXR_NS::UsdImagingCreateSceneIndicesInfo& createInfo, + PXR_NS::HdSceneIndexBaseRefPtr& finalSceneIndex, + PXR_NS::UsdImagingStageSceneIndexRefPtr& stageSceneIndex, + const PXR_NS::SdfPath& inoutPreFix, + void* dccNode); }; } //End of namespace FVP_NS_DEF diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataAbstractFactory.h b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataAbstractFactory.h index a24275406e..f0830c523a 100644 --- a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataAbstractFactory.h +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataAbstractFactory.h @@ -30,6 +30,13 @@ class DataProducerSceneIndexDataAbstractFactory /// The DCC will create a subclass of DataProducerSceneIndexDataBaseRefPtr with specific DCC variables that Flow viewport cannot manage since it's DCC agnostic virtual PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr createDataProducerSceneIndexDataBase( const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters& params) = 0; + + /** The DCC will create a subclass of DataProducerSceneIndexDataBaseRefPtr with specific DCC variables that Flow viewport cannot manage since it's DCC agnostic + * This function is specific for Usd Stages + */ + virtual PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr createDataProducerSceneIndexDataBaseForUsdStage( + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params) = 0; + }; }//End of namespace FVP_NS_DEF { diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.cpp b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.cpp index 213267280c..cc569f07c6 100644 --- a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.cpp +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.cpp @@ -21,6 +21,8 @@ //Local headers #include "fvpDataProducerSceneIndexDataBase.h" #include "flowViewport/sceneIndex/fvpParentDataModifierSceneIndex.h" +#include "flowViewport/sceneIndex/fvpPathInterfaceSceneIndex.h" +#include "flowViewport/API/fvpViewportAPITokens.h" //Hydra headers #include @@ -36,6 +38,7 @@ #include #include #include +#include PXR_NAMESPACE_OPEN_SCOPE @@ -48,11 +51,23 @@ DataProducerSceneIndexDataBase::DataProducerSceneIndexDataBase(const CreationPar { _parentMatrix.SetIdentity(); - _dataProducerSceneIndex = params._customDataProducerSceneIndex; - _customDataProducerSceneIndexRootPathForInsertion = params._customDataProducerSceneIndexRootPathForInsertion; - _lastSceneIndexChain = params._customDataProducerSceneIndex; - _rendererNames = params._rendererNames; - _dccNode = params._dccNode; + _dataProducerSceneIndex = params._customDataProducerSceneIndex; + _prefix = params._prefix; + _lastSceneIndexChain = params._customDataProducerSceneIndex; + _rendererNames = params._rendererNames; + _dccNode = params._dccNode; +} + +//For Usd stages +DataProducerSceneIndexDataBase::DataProducerSceneIndexDataBase(const CreationParametersForUsdStage& params) +{ + _parentMatrix.SetIdentity(); + + _dataProducerSceneIndex = nullptr;//Will be set later + _prefix = params._prefix; + _lastSceneIndexChain = nullptr;//Will be set later + _rendererNames = FvpViewportAPITokens->allRenderers; + _dccNode = params._dccNode; } void DataProducerSceneIndexDataBase::UpdateHydraTransformFromParentPath() @@ -119,7 +134,7 @@ void DataProducerSceneIndexDataBase::AddParentPrimToSceneIndex() //We are creating a XForm prim which has only 2 attributes a matrix and a visibility. //This prim will be the parent of all data producer scene index primitives so we can change their transform or visibility from the parent HdRetainedSceneIndex::AddedPrimEntry parentPrimEntry; - parentPrimEntry.primPath = _parentPath; + parentPrimEntry.primPath = _prefix; parentPrimEntry.primType = HdTokens->transform; parentPrimEntry.dataSource = HdRetainedContainerDataSource::New( HdXformSchemaTokens->xform, @@ -143,38 +158,71 @@ void DataProducerSceneIndexDataBase::RemoveParentPrimFromSceneIndex() return; } - _retainedSceneIndex->RemovePrims({ _parentPath}); + _retainedSceneIndex->RemovePrims({ _prefix}); _visible = false; } void DataProducerSceneIndexDataBase::_CreateSceneIndexChainForDataProducerSceneIndex() { - //Create a parent path to parent the whole _dataProducerSceneIndex prims, try to use the DCC node name + if (_dccNode){ + _CreateSceneIndexChainForDataProducerSceneIndexWithDCCNode(_dataProducerSceneIndex); + } + else{ + _CreateSceneIndexChainForDataProducerSceneIndexWithoutDCCNode(_dataProducerSceneIndex); + } +} + +//Callback for UsdImagingCreateSceneIndicesInfo.OverridesSceneIndexCallback as we want to insert scene indices +// before the flattening scene index from the usd stage scene indices +HdSceneIndexBaseRefPtr DataProducerSceneIndexDataBase::_CreateUsdStageSceneIndexChain(HdSceneIndexBaseRefPtr const & inputStageSceneIndex) +{ + _CreateSceneIndexChainForDataProducerSceneIndexWithDCCNode(inputStageSceneIndex); + return _lastSceneIndexChain; +} + +void DataProducerSceneIndexDataBase::_CreateSceneIndexChainForUsdStageSceneIndex(CreationParametersForUsdStage& params) +{ + //Set the overridesSceneIndexCallback to insert our scene indices chain after the stage scene index and before the flatten scene index + //If we don't do so, we cannot add a parent which will apply its matrix to the children because of the flatten scene index in the usd stage chain. + params._createInfo.overridesSceneIndexCallback = std::bind(&DataProducerSceneIndexDataBase::_CreateUsdStageSceneIndexChain, this, std::placeholders::_1); + + //Create the scene indices chain + UsdImagingSceneIndices sceneIndices = UsdImagingCreateSceneIndices(params._createInfo); + params._finalSceneIndex = sceneIndices.finalSceneIndex; + params._stageSceneIndex = sceneIndices.stageSceneIndex; + + _lastSceneIndexChain = sceneIndices.finalSceneIndex; +} + +void DataProducerSceneIndexDataBase::_CreateSceneIndexChainForDataProducerSceneIndexWithDCCNode(HdSceneIndexBaseRefPtr const & inputSceneIndex) +{ + //Create a parent path to parent the whole inputSceneIndex prims, try to use the DCC node name std::string nodeName = GetDCCNodeName(); + if (nodeName.empty()){ - _parentPath = SdfPath(TfStringPrintf("/DataProducerSI_%p", &(*_dataProducerSceneIndex))); + _prefix = _prefix.AppendPath(SdfPath(TfStringPrintf("DataProducerSI_%p", &(*inputSceneIndex)))); }else{ //A nodeName was provided by the DCC implementation, and it was sanitized for Hydra - _parentPath = SdfPath(std::string("/")+nodeName); + _prefix = _prefix.AppendPath(SdfPath(nodeName)); } - //Create a retainedsceneindex to inject a parent path to the be the parent of _dataProducerSceneIndex + //Create a retainedsceneindex to inject a parent path to the be the parent of inputSceneIndex _retainedSceneIndex = HdRetainedSceneIndex::New(); - // Add a prim inside which will be the parent of _dataProducerSceneIndex, its SdfPath will updated in _inOutData._parentPath + // Add a prim inside which will be the parent of inputSceneIndex, its SdfPath will updated in _inOutData._parentPath AddParentPrimToSceneIndex(); //Create a filtering scene index to update the information (transform, visibility,...) from the parent prim. - _parentDataModifierSceneIndex = ParentDataModifierSceneIndex::New(_retainedSceneIndex, _parentPath, _parentMatrix, true); + _parentDataModifierSceneIndex = ParentDataModifierSceneIndex::New(_retainedSceneIndex, _prefix, _parentMatrix, true); - //Add a prefixing scene index to _dataProducerSceneIndex to set the parent which we added to the retainedsceneindex - HdPrefixingSceneIndexRefPtr prefixingSceneIndex = HdPrefixingSceneIndex::New(_dataProducerSceneIndex, _parentPath); + //Add a prefixing scene index to inputSceneIndex to set the parent which we added to the retainedsceneindex + HdPrefixingSceneIndexRefPtr prefixingSceneIndex = HdPrefixingSceneIndex::New(inputSceneIndex, _prefix); //Use a merging scene index to merge the prefixing and the retainedsceneindex HdMergingSceneIndexRefPtr mergingSceneIndex = HdMergingSceneIndex::New(); mergingSceneIndex->AddInputScene(_parentDataModifierSceneIndex, SdfPath::AbsoluteRootPath()); mergingSceneIndex->AddInputScene(prefixingSceneIndex, SdfPath::AbsoluteRootPath()); - //Add a flattening scene index to the merging scene index, flatten only transform and visibility, meaning that transform and visibility should not have been already flatten previously ! + //Add a flattening scene index to the merging scene index, flatten only transform and visibility static HdContainerDataSourceHandle const flattenedTransformAndVisibilityDataSourceHandle = HdRetainedContainerDataSource::New( HdVisibilitySchema::GetSchemaToken(), @@ -183,7 +231,19 @@ void DataProducerSceneIndexDataBase::_CreateSceneIndexChainForDataProducerSceneI HdMakeDataSourceContainingFlattenedDataSourceProvider::Make() ); - _lastSceneIndexChain = HdFlatteningSceneIndex::New(mergingSceneIndex, flattenedTransformAndVisibilityDataSourceHandle);//Flatten + _lastSceneIndexChain = HdFlatteningSceneIndex::New(mergingSceneIndex, flattenedTransformAndVisibilityDataSourceHandle);//Flattening scene index to apply transform/visibility on children +} + +void DataProducerSceneIndexDataBase::_CreateSceneIndexChainForDataProducerSceneIndexWithoutDCCNode(HdSceneIndexBaseRefPtr const & inputSceneIndex) +{ + HdSceneIndexBaseRefPtr sceneIndex = inputSceneIndex; + if ( (!_prefix.IsEmpty()) && (_prefix != SdfPath::AbsoluteRootPath()) ){ + //Add a prefixing scene index to inputSceneIndex + sceneIndex = HdPrefixingSceneIndex::New(sceneIndex, _prefix); + } + + //Add a PathInterfaceSceneIndex for selection + _lastSceneIndexChain = sceneIndex; } }//end of namespace FVP_NS_DEF diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.h b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.h index d25f35ec21..bc204da973 100644 --- a/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.h +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpDataProducerSceneIndexDataBase.h @@ -23,6 +23,7 @@ //Hydra headers #include #include +#include //The Pixar's namespace needs to be at the highest namespace level for TF_DECLARE_WEAK_AND_REF_PTRS to work. PXR_NAMESPACE_OPEN_SCOPE @@ -44,27 +45,46 @@ TF_DECLARE_WEAK_AND_REF_PTRS(DataProducerSceneIndexDataBase);//Be able to use Re { CreationParameters( const HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, const std::string& rendererNames, - const SdfPath& customDataProducerSceneIndexRootPathForInsertion, + const SdfPath& prefix, void* dccNode) : _customDataProducerSceneIndex(customDataProducerSceneIndex), _rendererNames(rendererNames), - _customDataProducerSceneIndexRootPathForInsertion(customDataProducerSceneIndexRootPathForInsertion),_dccNode(dccNode) + _prefix(prefix),_dccNode(dccNode) {} //See below for an explanation of these parameters const HdSceneIndexBaseRefPtr& _customDataProducerSceneIndex; const std::string& _rendererNames; - const SdfPath& _customDataProducerSceneIndexRootPathForInsertion; + const SdfPath& _prefix; void* _dccNode; }; + struct CreationParametersForUsdStage + { + CreationParametersForUsdStage(UsdImagingCreateSceneIndicesInfo& createInfo, HdSceneIndexBaseRefPtr& finalSceneIndex, + UsdImagingStageSceneIndexRefPtr& stageSceneIndex, const SdfPath& prefix, void* dccNode) + : _createInfo(createInfo), _finalSceneIndex(finalSceneIndex), _stageSceneIndex(stageSceneIndex), _prefix(prefix),_dccNode(dccNode) + {} + + //See below for an explanation of these parameters + UsdImagingCreateSceneIndicesInfo& _createInfo; + HdSceneIndexBaseRefPtr& _finalSceneIndex; + UsdImagingStageSceneIndexRefPtr& _stageSceneIndex; + const SdfPath& _prefix; + void* _dccNode; + }; + ~DataProducerSceneIndexDataBase() override = default; virtual void AddParentPrimToSceneIndex(); virtual void RemoveParentPrimFromSceneIndex(); + //Used to set the usd stage scene indices + void SetDataProducerSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) {_dataProducerSceneIndex = sceneIndex;} + void SetDataProducerLastSceneIndexChain(const HdSceneIndexBaseRefPtr& sceneIndex) {_lastSceneIndexChain = sceneIndex;} + const HdSceneIndexBaseRefPtr& GetDataProducerSceneIndex() const {return _dataProducerSceneIndex;} const HdSceneIndexBaseRefPtr& GetDataProducerLastSceneIndexChain() const {return _lastSceneIndexChain;} - const SdfPath& GetCustomDataProducerSceneIndexRootPathForInsertion()const{return _customDataProducerSceneIndexRootPathForInsertion;} + const SdfPath& GetPrefix()const{return _prefix;} const std::string& GetRendererNames() const {return _rendererNames;} /// Provide the node name from the DCC to be overriden in a DCC specific subclass @@ -76,23 +96,30 @@ TF_DECLARE_WEAK_AND_REF_PTRS(DataProducerSceneIndexDataBase);//Be able to use Re protected: void _CreateSceneIndexChainForDataProducerSceneIndex(); + void _CreateSceneIndexChainForDataProducerSceneIndexWithDCCNode(HdSceneIndexBaseRefPtr const & inputSceneIndex); + void _CreateSceneIndexChainForDataProducerSceneIndexWithoutDCCNode(HdSceneIndexBaseRefPtr const & inputSceneIndex); + void _CreateSceneIndexChainForUsdStageSceneIndex(CreationParametersForUsdStage& params); + + //Callback for UsdImagingCreateSceneIndicesInfo.OverridesSceneIndexCallback + //Set the overridesSceneIndexCallback to insert our scene indices chain after the stage scene index and before the flatten scene index + //If we don't do so, we cannot add a parent which will apply its matrix to the children because of the flatten scene index in the usd stage chain. + PXR_NS::HdSceneIndexBaseRefPtr _CreateUsdStageSceneIndexChain(PXR_NS::HdSceneIndexBaseRefPtr const & inputStageSceneIndex); DataProducerSceneIndexDataBase(const CreationParameters& params); + DataProducerSceneIndexDataBase(const CreationParametersForUsdStage& params); /// data producer scene index HdSceneIndexBaseRefPtr _dataProducerSceneIndex = nullptr; /// data producer scene index rootPath for insertion (used in HdRenderIndex::InsertSceneIndex) - SdfPath _customDataProducerSceneIndexRootPathForInsertion; + SdfPath _prefix; /// Are the Hydra renderer(s) to which this scene index should be applied (e.g : "GL, Arnold") or DataProducerSceneIndexInterface::allViewports to apply to all viewports std::string _rendererNames; - /// Is the DCC node so a MObject* for Maya + /// Is the DCC node so a MObject* DAG node for Maya void* _dccNode; //The following members are optional and only used when a dccNode was passed in the constructor /** Is a filtering scene index that modifies the parent prim from the retained scene index to update the transform/visibility when it is updated in the DCC. It is used only when a dccNode was passed.*/ ParentDataModifierSceneIndexRefPtr _parentDataModifierSceneIndex = nullptr; - /// ParentPath prim used to be the parent of all prims from _dataProducerSceneIndex, used only when a dccNode was passed - SdfPath _parentPath; /// Is the last scene index of the scene index chain when a dccNode was passed. HdSceneIndexBaseRefPtr _lastSceneIndexChain = nullptr; /// Is the retained scene index holding the parent prim for _dataProducerSceneIndex. It is used only when a dccNode was passed. diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp index f02d04b32d..19e2b5311e 100644 --- a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp @@ -77,8 +77,7 @@ void ViewportInformationAndSceneIndicesPerViewportData::_AddAllDataProducerScene for (const auto& dataProducerSceneIndexData : _dataProducerSceneIndicesData){ // Add the data producer scene index to the merging scene index if (dataProducerSceneIndexData && dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain()) { - _renderIndexProxy->InsertSceneIndex(dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain(), - dataProducerSceneIndexData->GetCustomDataProducerSceneIndexRootPathForInsertion()); + _renderIndexProxy->InsertSceneIndex(dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain(), SdfPath::AbsoluteRootPath()); } } } diff --git a/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp b/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp index 00f139ab55..90bedcb498 100644 --- a/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp +++ b/lib/flowViewport/API/samples/fvpDataProducerSceneIndexExample.cpp @@ -534,7 +534,8 @@ HdRetainedSceneIndex::AddedPrimEntry DataProducerSceneIndexExample::_CreateCubeP void DataProducerSceneIndexExample::addDataProducerSceneIndex() { if (!_dataProducerSceneIndexAdded && _hydraInterface){ - const bool res = _hydraInterface->addDataProducerSceneIndex(_retainedSceneIndex, _containerNode, PXR_NS::FvpViewportAPITokens->allViewports, PXR_NS::FvpViewportAPITokens->allRenderers, SdfPath::AbsoluteRootPath()); + SdfPath inoutPrefix = PXR_NS::SdfPath::AbsoluteRootPath(); + const bool res = _hydraInterface->addDataProducerSceneIndex(_retainedSceneIndex, inoutPrefix, _containerNode, PXR_NS::FvpViewportAPITokens->allViewports, PXR_NS::FvpViewportAPITokens->allRenderers); if (false == res){ TF_CODING_ERROR("_hydraInterface->addDataProducerSceneIndex returned false !"); } diff --git a/lib/flowViewport/CMakeLists.txt b/lib/flowViewport/CMakeLists.txt index e0b271b714..02ec6778e8 100644 --- a/lib/flowViewport/CMakeLists.txt +++ b/lib/flowViewport/CMakeLists.txt @@ -59,6 +59,7 @@ target_link_libraries(${TARGET_NAME} hd hdx sdf + usdImaging ${UFE_LIBRARY} PRIVATE ar diff --git a/lib/mayaHydra/hydraExtensions/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/CMakeLists.txt index a244dcacbd..7853c33c55 100644 --- a/lib/mayaHydra/hydraExtensions/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/CMakeLists.txt @@ -30,31 +30,54 @@ set(HEADERS # ----------------------------------------------------------------------------- # compiler configuration # ----------------------------------------------------------------------------- -target_compile_definitions(${TARGET_NAME} - PRIVATE - MAYAHYDRALIB_EXPORT - $<$:OSMac_> - # Copy-pasted from lib/mayaUsd/CMakeLists.txt -) - +if(DEFINED MAYAUSD_LOCATION) + target_compile_definitions(${TARGET_NAME} + PRIVATE + MAYAHYDRALIB_EXPORT + MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD + $<$:OSMac_> + # Copy-pasted from lib/mayaUsd/CMakeLists.txt + ) +else() + target_compile_definitions(${TARGET_NAME} + PRIVATE + MAYAHYDRALIB_EXPORT + $<$:OSMac_> + # Copy-pasted from lib/mayaUsd/CMakeLists.txt + ) +endif() + mayaHydra_compile_config(${TARGET_NAME}) -if(NOT BUILD_MAYAUSD_LIBRARY) - # ----------------------------------------------------------------------------- - # include directories - # ----------------------------------------------------------------------------- - target_include_directories(${TARGET_NAME} - PUBLIC - ${MAYA_INCLUDE_DIRS} - ${PYTHON_INCLUDE_DIR} - ${PXR_INCLUDE_DIRS} - ${BOOST_INCLUDE_DIR} - ${CMAKE_BINARY_DIR}/include - PRIVATE - $<$:${UFE_INCLUDE_DIR}> - ) +# ----------------------------------------------------------------------------- +# include directories +# ----------------------------------------------------------------------------- +if(DEFINED MAYAUSD_LOCATION) +target_include_directories(${TARGET_NAME} + PUBLIC + ${MAYA_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIR} + ${PXR_INCLUDE_DIRS} + ${BOOST_INCLUDE_DIR} + ${CMAKE_BINARY_DIR}/include + ${MAYAUSD_LOCATION}/include + PRIVATE + $<$:${UFE_INCLUDE_DIR}> +) + else() + target_include_directories(${TARGET_NAME} + PUBLIC + ${MAYA_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIR} + ${PXR_INCLUDE_DIRS} + ${BOOST_INCLUDE_DIR} + ${CMAKE_BINARY_DIR}/include + PRIVATE + $<$:${UFE_INCLUDE_DIR}> + ) + endif() - target_compile_definitions(${TARGET_NAME} +target_compile_definitions(${TARGET_NAME} PUBLIC PXR_PLUGINPATH_NAME=${PXR_OVERRIDE_PLUGINPATH_NAME} $<$:TBB_USE_DEBUG> @@ -75,8 +98,7 @@ if(NOT BUILD_MAYAUSD_LIBRARY) # this flag is needed when building maya-usd in Maya $<$:WIN32> - ) -endif() +) if(DEFINED MAYAUSD_VERSION) target_compile_definitions(${TARGET_NAME} @@ -94,14 +116,43 @@ endif() # ----------------------------------------------------------------------------- # link libraries # ----------------------------------------------------------------------------- -if(BUILD_MAYAUSD_LIBRARY) +if(DEFINED MAYAUSD_LOCATION) + find_library(MAYAUSD_API_LIBRARY NAMES mayaUsdAPI PATHS ${MAYAUSD_LOCATION}/lib NO_DEFAULT_PATH) + if(NOT MAYAUSD_API_LIBRARY) + message(WARNING "Could not find mayaUsdAPI library.") + endif() target_link_libraries(${TARGET_NAME} - PUBLIC - mayaUsd + PUBLIC + ar + gf + hd + hdx + js + kind + plug + sdf + tf + trace + usd + usdGeom + usdImaging + usdImagingGL + usdLux + usdRender + usdRi + usdShade + usdSkel + usdUtils + ufeExtensions + flowViewport + ${MAYAUSD_API_LIBRARY} + ${MAYA_LIBRARIES} PRIVATE $<$:hio> + ${PYTHON_LIBRARIES} + $<$:${UFE_LIBRARY}> ) -else() +else() target_link_libraries(${TARGET_NAME} PUBLIC ar diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt index f9188eb888..38ed2f1725 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt @@ -16,6 +16,7 @@ target_sources(${TARGET_NAME} mayaHydraSceneIndexDataFactoriesSetup.cpp mayaHydraMayaFilteringSceneIndexData.cpp mayaHydraMayaFilteringSceneIndexDataConcreteFactory.cpp + mayaHydraMayaUsdProxyShapeSceneIndex.cpp ) set(HEADERS @@ -32,6 +33,7 @@ set(HEADERS mayaHydraSceneIndexDataFactoriesSetup.h mayaHydraMayaFilteringSceneIndexData.h mayaHydraMayaFilteringSceneIndexDataConcreteFactory.h + mayaHydraMayaUsdProxyShapeSceneIndex.h ) # ----------------------------------------------------------------------------- diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.cpp index 33c40440b2..d5cff83d4d 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.cpp @@ -84,6 +84,19 @@ PXR_NAMESPACE_USING_DIRECTIVE MayaDataProducerSceneIndexData::MayaDataProducerSceneIndexData(const FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters& params) : FVP_NS_DEF::DataProducerSceneIndexDataBase(params) { + CreateNodeCallbacks(); + _CreateSceneIndexChainForDataProducerSceneIndex(); +} + +MayaDataProducerSceneIndexData::MayaDataProducerSceneIndexData(FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params) + : FVP_NS_DEF::DataProducerSceneIndexDataBase(params) +{ + CreateNodeCallbacks(); + _CreateSceneIndexChainForUsdStageSceneIndex(params); +} + +void MayaDataProducerSceneIndexData::CreateNodeCallbacks() +{ //When the user has passed a maya node we are adding callbacks on various changes to be able to act on the data producer scene index prims automatically if (_dccNode){ MObject* mObj = reinterpret_cast(_dccNode); @@ -93,9 +106,6 @@ MayaDataProducerSceneIndexData::MayaDataProducerSceneIndexData(const FVP_NS_DEF: _CopyMayaNodeTransform();//Copy it so that the classes created in _CreateSceneIndexChainForDataProducerSceneIndex have the up to date matrix - //The user provided a DCC node, it's a maya MObject in maya hydra - _CreateSceneIndexChainForDataProducerSceneIndex(); - MCallbackId cbId = MNodeMessage::addAttributeChangedCallback(*mObj, attributeChangedCallback, this); if (cbId){ _nodeMessageCallbackIds.append(cbId); diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.h b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.h index e023a8829b..0dc9467a75 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexData.h @@ -42,6 +42,11 @@ TF_DECLARE_WEAK_AND_REF_PTRS(MayaDataProducerSceneIndexData);//Be able to use Re return TfCreateRefPtr(new MayaDataProducerSceneIndexData(params)); } + ///Is the way to get access to a new instance of MayaDataProducerSceneIndexData using ref counting for Usd Stages + static TfRefPtr New(FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params) { + return TfCreateRefPtr(new MayaDataProducerSceneIndexData(params)); + } + ///Destructor ~MayaDataProducerSceneIndexData() override; @@ -56,7 +61,9 @@ TF_DECLARE_WEAK_AND_REF_PTRS(MayaDataProducerSceneIndexData);//Be able to use Re private: MayaDataProducerSceneIndexData(const FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters& params); - + MayaDataProducerSceneIndexData(FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params); + + void CreateNodeCallbacks(); void _CopyMayaNodeTransform(); //The following members are optional and used only when a dccNode was passed in the constructor of DataProducerSceneIndexDataBase diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.cpp index 14c144b627..7d04de20a0 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.cpp @@ -26,4 +26,10 @@ MayaDataProducerSceneIndexDataConcreteFactory::createDataProducerSceneIndexDataB return PXR_NS::MayaDataProducerSceneIndexData::New(params); } +PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr +MayaDataProducerSceneIndexDataConcreteFactory::createDataProducerSceneIndexDataBaseForUsdStage(PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params) +{ + return PXR_NS::MayaDataProducerSceneIndexData::New(params); +} + }//end of namespace MAYAHYDRA_NS_DEF \ No newline at end of file diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.h b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.h index 8fade9ffed..d7abcdcb76 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaDataProducerSceneIndexDataConcreteFactory.h @@ -33,6 +33,12 @@ class MayaDataProducerSceneIndexDataConcreteFactory : public Fvp::DataProducerSc /// CreateDataProducerSceneIndexDataBase creates a subclass of DataProducerSceneIndexDataBaseRefPtr with specific DCC variables that flow viewport cannot manage since it's DCC agnostic PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr createDataProducerSceneIndexDataBase(const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters& params) override; + + /** The DCC will create a subclass of DataProducerSceneIndexDataBaseRefPtr with specific DCC variables that Flow viewport cannot manage since it's DCC agnostic + * This function is specific for Usd Stages + */ + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr createDataProducerSceneIndexDataBaseForUsdStage( + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParametersForUsdStage& params)override; }; }//end of namespace MAYAHYDRA_NS_DEF diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp new file mode 100644 index 0000000000..b938971429 --- /dev/null +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp @@ -0,0 +1,134 @@ +// +// Copyright 2023 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "mayaHydraMayaUsdProxyShapeSceneIndex.h" + +#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) + +//Maya headers +#include //For timeChanged callback + +//mayaHydra headers +#include "ufeExtensions/Global.h" + +PXR_NAMESPACE_OPEN_SCOPE + +namespace MAYAHYDRA_NS_DEF { + +MayaUsdProxyShapeSceneIndex::MayaUsdProxyShapeSceneIndex(const MAYAUSDAPI_NS::ProxyStage& proxyStage, + const HdSceneIndexBaseRefPtr& sceneIndexChainLastElement, + const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex, + const MObjectHandle& dagNodeHandle) + : ParentClass(sceneIndexChainLastElement) + , _usdImagingStageSceneIndex(usdImagingStageSceneIndex) + , _proxyStage(proxyStage) + , _dagNodeHandle(dagNodeHandle) +{ + TfWeakPtr ptr(this); + TfNotice::Register(ptr, &MayaUsdProxyShapeSceneIndex::_StageSet); + TfNotice::Register(ptr, &MayaUsdProxyShapeSceneIndex::_ObjectsChanged); + + _timeChangeCallbackId = MEventMessage::addEventCallback("timeChanged", onTimeChanged, this); +} + +MayaUsdProxyShapeSceneIndex::~MayaUsdProxyShapeSceneIndex() +{ + MMessage::removeCallback(_timeChangeCallbackId); +} + +MayaUsdProxyShapeSceneIndexRefPtr MayaUsdProxyShapeSceneIndex::New(const MAYAUSDAPI_NS::ProxyStage& proxyStage, + const HdSceneIndexBaseRefPtr& sceneIndexChainLastElement, + const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex, + const MObjectHandle& dagNodeHandle) +{ + return TfCreateRefPtr(new MayaUsdProxyShapeSceneIndex(proxyStage, sceneIndexChainLastElement, usdImagingStageSceneIndex, dagNodeHandle)); +} + +void MayaUsdProxyShapeSceneIndex::onTimeChanged(void* data) +{ + auto* instance = reinterpret_cast(data); + if (!TF_VERIFY(instance)) { + return; + } + instance->UpdateTime(); +} + +void MayaUsdProxyShapeSceneIndex::UpdateTime() +{ + if (_usdImagingStageSceneIndex && _proxyStage.isValid() && _dagNodeHandle.isValid()) { + _usdImagingStageSceneIndex->SetTime(_proxyStage.getTime());//We have the possibility to scale and offset the time in _proxyShapeBase + } +} + +void MayaUsdProxyShapeSceneIndex::_StageSet(const MAYAUSDAPI_NS::ProxyStageSetNotice& notice) +{ + Populate(); +} + +void MayaUsdProxyShapeSceneIndex::_ObjectsChanged( + const MAYAUSDAPI_NS::ProxyStageObjectsChangedNotice& notice) +{ + _PopulateAndApplyPendingChanges(); +} + +void MayaUsdProxyShapeSceneIndex::_PopulateAndApplyPendingChanges() +{ + Populate(); + _usdImagingStageSceneIndex->ApplyPendingUpdates(); +} + +void MayaUsdProxyShapeSceneIndex::Populate() +{ + if (!_populated && _proxyStage.isValid()) { + auto stage = _proxyStage.getUsdStage(); + // Check whether the pseudo-root has children + if (stage && (!stage->GetPseudoRoot().GetChildren().empty())) { + _usdImagingStageSceneIndex->SetStage(stage); + // Set the initial time + UpdateTime(); + _populated = true; + } + } +} + +Ufe::Path MayaUsdProxyShapeSceneIndex::InterpretRprimPath( + const HdSceneIndexBaseRefPtr& sceneIndex, + const SdfPath& path) +{ + if (MayaUsdProxyShapeSceneIndexRefPtr proxyShapeSceneIndex = TfStatic_cast(sceneIndex)) { + MDagPath dagPath(MDagPath::getAPathTo(proxyShapeSceneIndex->_dagNodeHandle.object())); + return Ufe::Path( + { UfeExtensions::dagPathToUfePathSegment(dagPath), UfeExtensions::sdfPathToUfePathSegment(path, UfeExtensions::getUsdRunTimeId()) }); + } + + return Ufe::Path(); +} + +// satisfying HdSceneIndexBase +HdSceneIndexPrim MayaUsdProxyShapeSceneIndex::GetPrim(const SdfPath& primPath) const +{ + return _GetInputSceneIndex()->GetPrim(primPath); +} + +SdfPathVector MayaUsdProxyShapeSceneIndex::GetChildPrimPaths(const SdfPath& primPath) const +{ + return _GetInputSceneIndex()->GetChildPrimPaths(primPath); +} + +} // namespace MAYAUSD_NS_DEF + +PXR_NAMESPACE_CLOSE_SCOPE +#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h new file mode 100644 index 0000000000..90b0f8beb5 --- /dev/null +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h @@ -0,0 +1,111 @@ +// +// Copyright 2023 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H +#define MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H + +#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) +//MayaHydra headers +#include "mayaHydraLib/api.h" +#include "mayaHydraLib/mayaHydra.h" + +//MayaUsdAPI headers +#include +#include + +//Usd/Hydra headers +#include +#include +#include // In USD 23.11+ +#include + +//Maya headers +#include +#include + +//Ufe headers +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +namespace MAYAHYDRA_NS_DEF { + +class MayaUsdProxyShapeSceneIndex; +TF_DECLARE_WEAK_AND_REF_PTRS(MayaUsdProxyShapeSceneIndex); + +/// +/// Simply wraps single stage scene index for initial stage assignment and population +/// +class MayaUsdProxyShapeSceneIndex : public HdSingleInputFilteringSceneIndexBase +{ +public: + using ParentClass = HdSingleInputFilteringSceneIndexBase; + + static MayaUsdProxyShapeSceneIndexRefPtr + New(const MAYAUSDAPI_NS::ProxyStage& proxyStage, + const HdSceneIndexBaseRefPtr& sceneIndexChainLastElement, + const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex, + const MObjectHandle& dagNodeHandle); + + // From HdSceneIndexBase + HdSceneIndexPrim GetPrim(const SdfPath& primPath) const override; + SdfPathVector GetChildPrimPaths(const SdfPath& primPath) const override; + + MayaUsdProxyShapeSceneIndex(const MAYAUSDAPI_NS::ProxyStage& proxyStage, + const HdSceneIndexBaseRefPtr& sceneIndexChainLastElement, + const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex, + const MObjectHandle& dagNodeHandle); + + virtual ~MayaUsdProxyShapeSceneIndex(); + + void Populate(); + void UpdateTime(); + static Ufe::Path InterpretRprimPath(const HdSceneIndexBaseRefPtr& sceneIndex,const SdfPath& path); + + //From HdSingleInputFilteringSceneIndexBase + void _PrimsAdded(const HdSceneIndexBase& sender, const HdSceneIndexObserver::AddedPrimEntries& entries) override{ + _SendPrimsAdded(entries); + } + void _PrimsRemoved(const HdSceneIndexBase& sender, const HdSceneIndexObserver::RemovedPrimEntries& entries)override{ + _SendPrimsRemoved(entries); + } + void _PrimsDirtied(const HdSceneIndexBase& sender, const HdSceneIndexObserver::DirtiedPrimEntries& entries)override{ + _SendPrimsDirtied(entries); + } + +private: + void _ObjectsChanged(const MAYAUSDAPI_NS::ProxyStageObjectsChangedNotice& notice); + void _StageSet(const MAYAUSDAPI_NS::ProxyStageSetNotice& notice); + void _PopulateAndApplyPendingChanges(); + +private: + static void onTimeChanged(void* data); + + UsdImagingStageSceneIndexRefPtr _usdImagingStageSceneIndex {nullptr}; + MAYAUSDAPI_NS::ProxyStage _proxyStage; + std::atomic _populated { false }; + MCallbackId _timeChangeCallbackId = 0; + MObjectHandle _dagNodeHandle; +}; + +} // namespace MAYAHYDRA_NS_DEF + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD + +#endif //MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H \ No newline at end of file diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp index c80c28ab09..d59f89c104 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp @@ -14,11 +14,13 @@ // limitations under the License. // -#include -#include +#include "mayaHydraLib/hydraUtils.h" +#include "mayaHydraLib/sceneIndex/registration.h" +#include "mayaHydraLib/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h" #include #include +#include #include #include @@ -28,18 +30,9 @@ #include #include -// The SceneIndex plugin required for MaterialX binding to work will no longer be needed -// after 23.08 hopefully. Pixar has made changed to USD that should handle this case. -#if PXR_VERSION < 2308 -// Temp workaround to get the code to compile. -// this will not be required once the pull request to USD header is complete. -// Details of the issue - https://groups.google.com/g/usd-interest/c/0kyY3Z2sgjo -// TODO: remove conditional #undefs after PR is complete. -#ifdef interface -#undef interface +#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) + #include #endif -#include -#endif //PXR_VERSION #include #include @@ -119,6 +112,7 @@ class PathInterfaceSceneIndex : public Fvp::PathInterfaceSceneIndexBase SdfPath _sceneIndexPathPrefix; }; +constexpr char kMayaUsdProxyShapeNode[] = { "mayaUsdProxyShape" }; } PXR_NAMESPACE_OPEN_SCOPE @@ -129,91 +123,35 @@ PXR_NAMESPACE_OPEN_SCOPE // Remove this once the code has been moved to the MayaHydra namespace. using namespace MayaHydra; -/* To add a custom scene index, a customer plugin must: - 1. Define a Maya dag node via the MPxNode interface, and register it MFnPlugin::registerNode. This -is typically done inside a Maya plug-in initialize function. - 2. Define a HdSceneIndexPlugin which contains an _AppendSceneIndex method. The _AppendSceneIndex -method will be called for every Maya node added into the scene. A customer is responsible for type -checking the node for the one defined and also instantiate the corresponding scene index inside -_AppendSceneIndex. The scene index returned by _AppendSceneIndex is then added to the render index -by Maya. - -For example here is how we do that process in the Maya USD plug-in : -// Some context : -// MayaUsdProxyShapeMayaNodeSceneIndexPlugin is a subclass of HdSceneIndexPlugin. -// MayaUsdProxyShapeBase is the base class for our Maya USD node. -// MayaUsd::MayaUsdProxyShapeSceneIndex is the scene index class for Maya USD where we load the -// stages. - -HdSceneIndexBaseRefPtr MayaUsdProxyShapeMayaNodeSceneIndexPlugin::_AppendSceneIndex( - const HdSceneIndexBaseRefPtr& inputScene, - const HdContainerDataSourceHandle& inputArgs) -{ - using HdMObjectDataSource = HdRetainedTypedSampledDataSource; - using HdMObjectDataSourceHandle = HdRetainedTypedSampledDataSource::Handle; - static TfToken dataSourceNodePathEntry("object"); - HdDataSourceBaseHandle dataSourceEntryPathHandle = inputArgs->Get(dataSourceNodePathEntry); - if (HdMObjectDataSourceHandle dataSourceEntryPath - = HdMObjectDataSource::Cast(dataSourceEntryPathHandle)) { - MObject dagNode = dataSourceEntryPath->GetTypedValue(0.0f); - MStatus status; - MFnDependencyNode dependNodeFn(dagNode, &status); - if (!TF_VERIFY(status, "Error getting MFnDependencyNode")) { - return nullptr; - } - - // Check that this node is a MayaUsdProxyShapeBase which is the base class for our Maya USD - // node - auto proxyShape = dynamic_cast(dependNodeFn.userNode()); - if (TF_VERIFY(proxyShape, "Error getting MayaUsdProxyShapeBase")) { - auto psSceneIndex = MayaUsd::MayaUsdProxyShapeSceneIndex::New(proxyShape); - // Flatten transforms, visibility, purpose, model, and material - // bindings over hierarchies. - return HdFlatteningSceneIndex::New(psSceneIndex); - } - } - - return nullptr; -} - -You may want to see the full source code in the Maya USD open source repository : -https://github.com/Autodesk/maya-usd/tree/dev/lib/mayaUsd/sceneIndex -*/ - -namespace { -constexpr char kDagNodeMessageName[] = { "dagNode" }; -} // MayaHydraSceneIndexRegistration is used to register a scene index for a given dag node type. MayaHydraSceneIndexRegistry::MayaHydraSceneIndexRegistry(const std::shared_ptr& renderIndexProxy) : _renderIndexProxy(renderIndexProxy) { - // Begin registering of custom scene indices for given node types - HdSceneIndexPluginRegistry& sceneIndexPluginRegistry - = HdSceneIndexPluginRegistry::GetInstance(); - // Ensure scene index plugin registration - std::vector customSceneIndexDescs; - sceneIndexPluginRegistry.GetPluginDescs(&customSceneIndexDescs); - if (customSceneIndexDescs.size() != 0) { - MCallbackId id; - MStatus status; - id = MDGMessage::addNodeAddedCallback( - _SceneIndexNodeAddedCallback, kDagNodeMessageName, this, &status); - if (TF_VERIFY(status == MS::kSuccess, "NodeAdded callback registration failed.")) - _sceneIndexDagNodeMessageCallbacks.append(id); - id = MDGMessage::addNodeRemovedCallback( - _SceneIndexNodeRemovedCallback, kDagNodeMessageName, this, &status); - if (TF_VERIFY(status == MS::kSuccess, "NodeRemoved callback registration failed.")) - _sceneIndexDagNodeMessageCallbacks.append(id); - - // Iterate over scene to find out existing node which will miss eventual dagNode added - // callbacks - MItDag nodesDagIt(MItDag::kDepthFirst, MFn::kInvalid); - for (; !nodesDagIt.isDone(); nodesDagIt.next()) { - MStatus status; - MObject dagNode(nodesDagIt.item(&status)); - if (TF_VERIFY(status == MS::kSuccess)) { - _AddSceneIndexForNode(dagNode); - } + MCallbackId id; + MStatus status; + id = MDGMessage::addNodeAddedCallback( + _SceneIndexNodeAddedCallback, kMayaUsdProxyShapeNode, this, &status);//We need only to monitor the MayaUsdProxyShapeNode + if (TF_VERIFY(status == MS::kSuccess, "NodeAdded callback registration failed.")) + _sceneIndexDagNodeMessageCallbacks.append(id); + id = MDGMessage::addNodeRemovedCallback( + _SceneIndexNodeRemovedCallback, kMayaUsdProxyShapeNode, this, &status);//We need only to monitor the MayaUsdProxyShapeNode + if (TF_VERIFY(status == MS::kSuccess, "NodeRemoved callback registration failed.")) + _sceneIndexDagNodeMessageCallbacks.append(id); + + static const MTypeId MAYAUSD_PROXYSHAPE_ID(0x58000095); //Hardcoded + + // Iterate over scene to find out existing node which will miss eventual dagNode added callbacks + MItDag nodesDagIt(MItDag::kDepthFirst, MFn::kInvalid); + for (; !nodesDagIt.isDone(); nodesDagIt.next()) { + MObject dagNode(nodesDagIt.item(&status)); + //Act only on MayaUsdProxyShapeBase nodes + MFnDependencyNode dep(dagNode); + if (MAYAUSD_PROXYSHAPE_ID != dep.typeId()) { + continue; + } + + if (TF_VERIFY(status == MS::kSuccess)) { + _AddSceneIndexForNode(dagNode); } } } @@ -223,17 +161,15 @@ MayaHydraSceneIndexRegistry::MayaHydraSceneIndexRegistry(const std::shared_ptr 2) - sceneIndexPluginPath = sceneIndexPluginPath.GetParentPath(); - auto it = _registrations.find(sceneIndexPluginPath); - if (it != _registrations.end()) { - return it->second; + const std::string& rprimPathAsString = rprimPath.GetString(); + for (auto& reg : _registrations){ + auto& key = reg.first.GetString(); + const size_t found = rprimPathAsString.find(key); + if (found != std::string::npos){ + return reg.second; + } } - + return nullptr; } @@ -254,10 +190,11 @@ MayaHydraSceneIndexRegistry::~MayaHydraSceneIndexRegistry() bool MayaHydraSceneIndexRegistry::_RemoveSceneIndexForNode(const MObject& dagNode) { MObjectHandle dagNodeHandle(dagNode); - auto it = _registrationsByObjectHandle.find(dagNodeHandle); + auto it = _registrationsByObjectHandle.find(dagNodeHandle); if (it != _registrationsByObjectHandle.end()) { MayaHydraSceneIndexRegistrationPtr registration(it->second); - _renderIndexProxy->RemoveSceneIndex(registration->rootSceneIndex); + Fvp::DataProducerSceneIndexInterface& dataProducerSceneIndexInterface = Fvp::DataProducerSceneIndexInterface::get(); + dataProducerSceneIndexInterface.removeViewportDataProducerSceneIndex(registration->rootSceneIndex); _registrationsByObjectHandle.erase(dagNodeHandle); _registrations.erase(registration->sceneIndexPathPrefix); return true; @@ -265,27 +202,94 @@ bool MayaHydraSceneIndexRegistry::_RemoveSceneIndexForNode(const MObject& dagNod return false; } -#if PXR_VERSION < 2308 -HdSceneIndexBaseRefPtr -MayaHydraSceneIndexRegistry::_AppendTerminalRenamingSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) -{ - // Get the list of renderer supported material network implementations. - TfTokenVector renderingContexts = - _renderIndexProxy.GetMaterialRenderContexts(); - - // Create remapping token pairs to help Hydra build the material networks. - std::map terminalRemapList; - for (const auto& terminal : renderingContexts) - terminalRemapList.emplace(TfToken(terminal.GetString()+":surface"), - HdMaterialTerminalTokens->surface); - return HdsiTerminalsResolvingSceneIndex::New(sceneIndex, terminalRemapList); -} -#endif // PXR_VERSION +#ifdef MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD +void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) +{ + //We receive only dag nodes of type MayaUsdProxyShapeNode + MAYAUSDAPI_NS::ProxyStage proxyStage(dagNode); + if (TF_VERIFY(proxyStage.isValid(), "Error getting MayaUsdAPIProxyStage")) { + MayaHydraSceneIndexRegistrationPtr registration(new MayaHydraSceneIndexRegistration()); + + //Add the usdimaging stage scene index chain as a data producer scene index in flow viewport + + //Since we want to insert a parent primitive for the stage scene index to be transformed or set visible/invisible, we need to set this scene indices chain + //before some of the instancing scene indices for UsdImaginsStageSceneIndex, and there is a slot for that purpose which is createInfo.overridesSceneIndexCallback + //With this callback you can insert some scene indices which will be applied before the prototype scene indices. + //This will be done inside Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex later + UsdImagingCreateSceneIndicesInfo createInfo; + + auto stage = proxyStage.getUsdStage(); + // Check whether the pseudo-root has children + if (stage && (!stage->GetPseudoRoot().GetChildren().empty())) { + createInfo.stage = stage;//Add the stage to the creation parameters + } + + MStatus status; + MDagPath dagPath(MDagPath::getAPathTo(dagNode, &status)); + if (TF_VERIFY(status == MS::kSuccess, "Incapable of finding dag path to given node")) { + registration->dagNode = MObjectHandle(dagNode); + // Construct the scene index path prefix appended to each rprim created by it. + // It is composed of the "scene index plugin's name" + "dag node name" + + // "disambiguator" The dag node name disambiguator is necessary in situation + // where node name isn't unique and may clash with other node defined by the + // same plugin. + MFnDependencyNode dependNodeFn(dagNode); + std::string dependNodeNameString (dependNodeFn.name().asChar()); + SanitizeNameForSdfPath(dependNodeNameString); + + registration->sceneIndexPathPrefix = + SdfPath::AbsoluteRootPath() + .AppendPath(SdfPath(dependNodeNameString + + (dependNodeFn.hasUniqueName() + ? "" + : "__" + std::to_string(_incrementedCounterDisambiguator++)))); + + + //We will get the following scene indices from Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex + HdSceneIndexBaseRefPtr finalSceneIndex = nullptr; + UsdImagingStageSceneIndexRefPtr stageSceneIndex = nullptr; + + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = + Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex(createInfo, finalSceneIndex, stageSceneIndex, + registration->sceneIndexPathPrefix, (void*)&dagNode); + if (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex){ + TF_CODING_ERROR("Error (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex) !"); + } + + //Create maya usd proxy shape scene index, since this scene index contains maya data, it cannot be added by the flow viewport API + auto mayaUsdProxyShapeSceneIndex = MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::New(proxyStage, finalSceneIndex, stageSceneIndex, MObjectHandle(dagNode)); + registration->pluginSceneIndex = mayaUsdProxyShapeSceneIndex; + registration->interpretRprimPathFn = &(MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::InterpretRprimPath); + mayaUsdProxyShapeSceneIndex->Populate(); + + registration->rootSceneIndex = registration->pluginSceneIndex; + + //Add the PathInterfaceSceneIndex which must be the last scene index, it is used for selection highlighting + registration->rootSceneIndex = PathInterfaceSceneIndex::New( + registration->rootSceneIndex, + registration->sceneIndexPathPrefix); -constexpr char kSceneIndexPluginSuffix[] = { - "MayaNodeSceneIndexPlugin" -}; // every scene index plugin compatible with the hydra viewport requires this suffix + //Set the chain back into the dataProducerSceneIndexData in both members + dataProducerSceneIndexData->SetDataProducerSceneIndex(registration->rootSceneIndex); + dataProducerSceneIndexData->SetDataProducerLastSceneIndexChain(registration->rootSceneIndex); + //Add this chain scene index to the render index proxy from all viewports + const bool bRes = Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageDataProducerSceneIndexDataBaseToAllViewports(dataProducerSceneIndexData); + if (false == bRes){ + TF_CODING_ERROR("Fvp::DataProducerSceneIndexInterfaceImp::get().addDataProducerSceneIndex returned false !"); + } + + // Add registration record if everything succeeded + _registrations.insert({ registration->sceneIndexPathPrefix, registration }); + _registrationsByObjectHandle.insert({ registration->dagNode, registration }); + } + } +} +#else +namespace +{ + constexpr char kSceneIndexPluginSuffix[] = {"MayaNodeSceneIndexPlugin"}; +} void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) { MFnDependencyNode dependNodeFn(dagNode); @@ -324,7 +328,7 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) HdRetainedContainerDataSource::New(kDataSourceNumEntries, sDataSourceEntryNames, values)); if (TF_VERIFY( registration->pluginSceneIndex, - "HdSceneIndexBase::AppendSceneIndex failed to create %s scene index from given " + "MayaHydraSceneIndexRegistry::_AddSceneIndexForNode failed to create %s scene index from given " "node type.", sceneIndexPluginName.c_str())) { @@ -349,15 +353,7 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) : "__" + std::to_string(_incrementedCounterDisambiguator++)))); registration->rootSceneIndex = registration->pluginSceneIndex; - #if PXR_VERSION < 2308 - // HYDRA-179 - // Inject TerminalsResolvingSceneIndex to get Hydra to handle material bindings. - // A simple string replacement for Hydra to identify the terminals based on the render context. - HdSceneIndexBaseRefPtr outSceneIndex = _AppendTerminalRenamingSceneIndex(registration->pluginSceneIndex); - // Sanity check - registration->rootSceneIndex = outSceneIndex ? outSceneIndex : registration->pluginSceneIndex; - #endif // PXR_VERSION - + // Because the path interface scene index must be the last one // in the chain, add the prefixing scene index here, instead of // relying on the render index proxy doing it for us. @@ -386,6 +382,7 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) } } } +#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD void MayaHydraSceneIndexRegistry::_SceneIndexNodeAddedCallback(MObject& dagNode, void* clientData) { diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h index 5de7b4f835..f5939a51cd 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h @@ -71,8 +71,6 @@ struct MayaHydraSceneIndexRegistration * type checking the node for the one defined and also instantiate the corresponding scene index * inside _AppendSceneIndex. The scene index returned by _AppendSceneIndex is then added to the * render index by Maya. - * - * See registration.cpp file for a code snippet. */ class MayaHydraSceneIndexRegistry { diff --git a/lib/mayaHydra/mayaPlugin/plugRegistryHelper.cpp b/lib/mayaHydra/mayaPlugin/plugRegistryHelper.cpp index 2bd9b5d287..6467ff7f12 100644 --- a/lib/mayaHydra/mayaPlugin/plugRegistryHelper.cpp +++ b/lib/mayaHydra/mayaPlugin/plugRegistryHelper.cpp @@ -29,10 +29,6 @@ #include #include -#if !defined(MAYAUSD_VERSION) -// y #error "MAYAUSD_VERSION is not defined" -#endif - #if !defined(MAYA_PY_VERSION) // y #error "MAYA_PY_VERSION is not defined" #endif diff --git a/lib/mayaHydra/mayaPlugin/plugin.cpp b/lib/mayaHydra/mayaPlugin/plugin.cpp index c75f7516b5..c1a10b222b 100644 --- a/lib/mayaHydra/mayaPlugin/plugin.cpp +++ b/lib/mayaHydra/mayaPlugin/plugin.cpp @@ -22,9 +22,6 @@ #include "viewCommand.h" #include -#if defined(MAYAUSD_VERSION) -#include -#endif #include @@ -93,10 +90,6 @@ PLUGIN_EXPORT MStatus initializePlugin(MObject obj) MStatus ret = MS::kSuccess; -#if defined(MAYAUSD_VERSION) - // Call one time registration of plugins compiled for same USD version as MayaUSD plugin. - MayaUsd::registerVersionedPlugins(); -#endif ret = PXR_NS::MayaHydraAdapter::Initialize(); if (!ret) { return ret; diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.cpp b/lib/mayaHydra/mayaPlugin/renderOverride.cpp index 77a7e81e5b..9d77715bad 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.cpp +++ b/lib/mayaHydra/mayaPlugin/renderOverride.cpp @@ -16,10 +16,8 @@ // Copyright 2023 Autodesk, Inc. All rights reserved. // -#if !defined(MAYAUSD_VERSION) // GL loading library needs to be included before any other OpenGL headers. #include -#endif #include "renderOverride.h" @@ -43,6 +41,7 @@ #include #include #include +#include #include #include @@ -60,10 +59,6 @@ #include -#if defined(MAYAUSD_VERSION) -#include -#include -#else namespace MayaUsd { // hash combiner taken from: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0814r0.pdf @@ -77,7 +72,7 @@ template inline void hash_combine(std::size_t& seed, const T& value seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } } // namespace MayaUsd -#endif + #include #include @@ -839,6 +834,9 @@ void MtohRenderOverride::ClearHydraResources() //We don't have any viewport using Hydra any more Fvp::ViewportInformationAndSceneIndicesPerViewportDataManager::Get().RemoveAllViewportsInformation(); + + //Remove the data producer scene indices that apply to all viewports + Fvp::DataProducerSceneIndexInterfaceImp::get().ClearDataProducerSceneIndicesThatApplyToAllViewports(); _mayaHydraSceneProducer.reset(); _selectionSceneIndex.Reset(); @@ -1099,12 +1097,24 @@ void MtohRenderOverride::_PopulateSelectionList( = _sceneIndexRegistry->GetSceneIndexRegistrationForRprim(pickedPath)) // Scene index is incompatible with UFE. Skip { - // Remove scene index plugin path prefix to obtain local picked path with + // Keep the path after the scene index plugin path prefix to obtain local picked path with // respect to current scene index. This is because the scene index was inserted // into the render index using a custom prefix. As a result the scene index // prefix will be prepended to rprims tied to that scene index automatically. - SdfPath localPath( - pickedPath.ReplacePrefix(registration->sceneIndexPathPrefix, SdfPath("/"))); + const std::string& sceneIndexPathPrefixAsString = registration->sceneIndexPathPrefix.GetString(); + const std::string& pickedPathAsString = pickedPath.GetString(); + std::string localPathAsString; + const size_t foundPlace = pickedPathAsString.find(sceneIndexPathPrefixAsString); + if (foundPlace == std::string::npos) { + TF_CODING_ERROR("pickedPathAsString.find(sceneIndexPathPrefixAsString) returned std::string::npos !"); + return; + } + + //Keep only the right part of the string after the prefix + const size_t placeToKeep = foundPlace + sceneIndexPathPrefixAsString.length(); + localPathAsString = pickedPathAsString.substr(placeToKeep, pickedPathAsString.length() - placeToKeep); + + const SdfPath localPath(localPathAsString); Ufe::Path interpretedPath(registration->interpretRprimPathFn( registration->pluginSceneIndex, localPath)); diff --git a/lib/mayaHydra/ufeExtensions/CMakeLists.txt b/lib/mayaHydra/ufeExtensions/CMakeLists.txt index a7cfa3a3a2..8bed7e13ff 100644 --- a/lib/mayaHydra/ufeExtensions/CMakeLists.txt +++ b/lib/mayaHydra/ufeExtensions/CMakeLists.txt @@ -26,18 +26,18 @@ target_compile_definitions(${TARGET_NAME} mayaHydra_compile_config(${TARGET_NAME}) -if(NOT BUILD_MAYAUSD_LIBRARY) - # ----------------------------------------------------------------------------- - # include directories - # ----------------------------------------------------------------------------- - target_include_directories(${TARGET_NAME} + +# ----------------------------------------------------------------------------- +# include directories +# ----------------------------------------------------------------------------- +target_include_directories(${TARGET_NAME} PUBLIC ${MAYA_INCLUDE_DIRS} ${CMAKE_BINARY_DIR}/include $<$:${UFE_INCLUDE_DIR}> - ) +) - target_compile_definitions(${TARGET_NAME} +target_compile_definitions(${TARGET_NAME} PUBLIC PXR_PLUGINPATH_NAME=${PXR_OVERRIDE_PLUGINPATH_NAME} $<$:TBB_USE_DEBUG> @@ -53,8 +53,7 @@ if(NOT BUILD_MAYAUSD_LIBRARY) # this flag is needed when building maya-usd in Maya $<$:WIN32> - ) -endif() +) if(DEFINED MAYAHYDRA_VERSION) target_compile_definitions(${TARGET_NAME} diff --git a/lib/mayaHydra/ufeExtensions/Global.cpp b/lib/mayaHydra/ufeExtensions/Global.cpp index ee86b77d7a..8b685a9b22 100644 --- a/lib/mayaHydra/ufeExtensions/Global.cpp +++ b/lib/mayaHydra/ufeExtensions/Global.cpp @@ -83,27 +83,28 @@ MDagPath ufeToDagPath(const Ufe::Path& ufePath) /// desired runtime id as a parameter. /// //! \return Ufe PathSegment -Ufe::PathSegment sdfPathToUfePathSegment(const SdfPath& usdPath, Ufe::Rtid rtid) +Ufe::PathSegment sdfPathToUfePathSegment(const SdfPath& usdPath, Ufe::Rtid rtid, int instanceIndex/*= ALL_INSTANCES*/) { + static const char separator = SdfPathTokens->childDelimiter.GetText()[0u]; + if (!TF_VERIFY(!usdPath.IsEmpty())) { // Return an empty segment. - return Ufe::PathSegment(Ufe::PathSegment::Components(), rtid, kSdfPathSeparator); + return Ufe::PathSegment(Ufe::PathSegment::Components(), rtid, separator); } std::string pathString = usdPath.GetString(); - // MAYA-128021: instances are not currently supported - // if (instanceIndex >= 0) { - // // Note here that we're taking advantage of the fact that identifiers - // // in SdfPaths must be C/Python identifiers; that is, they must *not* - // // begin with a digit. This means that when we see a path component at - // // the end of a USD path segment that does begin with a digit, we can - // // be sure that it represents an instance index and not a prim or other - // // USD entity. - // pathString += TfStringPrintf("%c%d", separator, instanceIndex); - //} - - return Ufe::PathSegment(pathString, rtid, kSdfPathSeparator); + if (instanceIndex >= 0) { + // Note here that we're taking advantage of the fact that identifiers + // in SdfPaths must be C/Python identifiers; that is, they must *not* + // begin with a digit. This means that when we see a path component at + // the end of a USD path segment that does begin with a digit, we can + // be sure that it represents an instance index and not a prim or other + // USD entity. + pathString += TfStringPrintf("%c%d", separator, instanceIndex); + } + + return Ufe::PathSegment(pathString, rtid, separator); } Ufe::PathSegment dagPathToUfePathSegment(const MDagPath& dagPath) diff --git a/lib/mayaHydra/ufeExtensions/Global.h b/lib/mayaHydra/ufeExtensions/Global.h index 88469d1c1f..405dab75d2 100644 --- a/lib/mayaHydra/ufeExtensions/Global.h +++ b/lib/mayaHydra/ufeExtensions/Global.h @@ -33,6 +33,9 @@ namespace UfeExtensions { using SdfPath = PXR_NS::SdfPath; +//Copied from usdImaging/usdImaging/delegate.h +static constexpr int ALL_INSTANCES = -1; + UFEEXTENSIONS_API Ufe::Rtid getMayaRunTimeId(); @@ -46,7 +49,7 @@ UFEEXTENSIONS_API MDagPath ufeToDagPath(const Ufe::Path& ufePath); UFEEXTENSIONS_API -Ufe::PathSegment sdfPathToUfePathSegment(const SdfPath& usdPath, Ufe::Rtid rtid); +Ufe::PathSegment sdfPathToUfePathSegment(const SdfPath& usdPath, Ufe::Rtid rtid, int instanceIndex = ALL_INSTANCES); UFEEXTENSIONS_API Ufe::PathSegment dagPathToUfePathSegment(const MDagPath& dagPath); diff --git a/test/lib/CMakeLists.txt b/test/lib/CMakeLists.txt index 21ca47b4f5..b8841bd142 100644 --- a/test/lib/CMakeLists.txt +++ b/test/lib/CMakeLists.txt @@ -1,55 +1,3 @@ -if(BUILD_MAYAUSD_LIBRARY) - # Unit test scripts. - set(TEST_SCRIPT_FILES - testMayaUsdConverter.py - testMayaUsdCreateStageCommands.py - testMayaUsdPythonImport.py - testMayaUsdLayerEditorCommands.py - testMayaUsdCacheId.py - ) - - if (UFE_FOUND AND MAYA_APP_VERSION VERSION_GREATER 2020) - list(APPEND TEST_SCRIPT_FILES - testMayaUsdDirtyScene.py - testMayaUsdProxyAccessor.py - ) - endif() - - # Interactive Unit test scripts. - set(INTERACTIVE_TEST_SCRIPT_FILES - testMayaUsdInteractiveLayerEditorCommands.py - testMayaUsdInteractiveMaterialsScopeName.py - ) - - foreach(script ${TEST_SCRIPT_FILES}) - mayaUsd_get_unittest_target(target ${script}) - mayaUsd_add_test(${target} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - PYTHON_MODULE ${target} - ENV - "LD_LIBRARY_PATH=${ADDITIONAL_LD_LIBRARY_PATH}" - ) - - # Add a ctest label to these tests for easy filtering. - set_property(TEST ${target} APPEND PROPERTY LABELS MayaUsd) - endforeach() - - foreach(script ${INTERACTIVE_TEST_SCRIPT_FILES}) - mayaUsd_get_unittest_target(target ${script}) - mayaUsd_add_test(${target} - INTERACTIVE - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - PYTHON_SCRIPT ${script} - ENV - "MAYA_PLUG_IN_PATH=${CMAKE_INSTALL_PREFIX}/lib/maya" - "LD_LIBRARY_PATH=${ADDITIONAL_LD_LIBRARY_PATH}" - ) - - # Add a ctest label to these tests for easy filtering. - set_property(TEST ${target} APPEND PROPERTY LABELS MayaUsd) - endforeach() -endif() - # # ----------------------------------------------------------------------------- # Special interactive test to be able to start Maya with test configurations. @@ -66,40 +14,6 @@ set_property(TEST ${target} APPEND PROPERTY DISABLED True) set_property(TEST ${target} APPEND PROPERTY LABELS Debugging) set_property(TEST ${target} APPEND PROPERTY ENVIRONMENT "MAYA_MODULE_PATH=${CMAKE_INSTALL_PREFIX}") -if(BUILD_MAYAUSD_LIBRARY) - # - # ----------------------------------------------------------------------------- - # Special case for plug tests - # ----------------------------------------------------------------------------- - set(TEST_PLUG_FILES - testMayaUsdPlugVersionCheck.py - ) - - foreach(script ${TEST_PLUG_FILES}) - mayaUsd_get_unittest_target(target ${script}) - mayaUsd_add_test(${target} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - PYTHON_MODULE ${target} - ENV - "LD_LIBRARY_PATH=${ADDITIONAL_LD_LIBRARY_PATH}" - "MAYA_PXR_PLUGINPATH_NAME=${CMAKE_CURRENT_BINARY_DIR}/usd/plugin/TestMayaUsdPlug" - ) - - # Add a ctest label to these tests for easy filtering. - set_property(TEST ${target} APPEND PROPERTY LABELS MayaUsd) - endforeach() - - # ----------------------------------------------------------------------------- - if (UFE_FOUND) - add_subdirectory(ufe) - add_subdirectory(mayaUsd) - endif() -endif() - if(BUILD_MAYAHYDRALIB) add_subdirectory(mayaUsd/render) endif() - -if(BUILD_MAYAUSD_LIBRARY) - add_subdirectory(usd) -endif() diff --git a/test/lib/mayaUsd/render/CMakeLists.txt b/test/lib/mayaUsd/render/CMakeLists.txt index 594e60600f..366751b2d2 100644 --- a/test/lib/mayaUsd/render/CMakeLists.txt +++ b/test/lib/mayaUsd/render/CMakeLists.txt @@ -1,8 +1,3 @@ -if(BUILD_MAYAUSD_LIBRARY) - add_subdirectory(pxrUsdMayaGL) - add_subdirectory(vp2RenderDelegate) -endif() - if(BUILD_MAYAHYDRALIB) add_subdirectory(mayaToHydra) endif() From 40facc0401d1da04701361bfb4e2c7395cde0fa2 Mon Sep 17 00:00:00 2001 From: David Lanier Date: Tue, 16 Jan 2024 18:06:47 +0100 Subject: [PATCH 02/25] Fixes from Sean code review. --- CMakeLists.txt | 7 + build.py | 2 +- cmake/modules/FindMayaUsd.cmake | 89 +++++++++++ doc/build.md | 2 +- lib/mayaHydra/hydraExtensions/CMakeLists.txt | 143 +++++------------- .../mayaHydraMayaUsdProxyShapeSceneIndex.cpp | 4 +- .../sceneIndex/registration.cpp | 136 ++++++++--------- 7 files changed, 209 insertions(+), 174 deletions(-) create mode 100644 cmake/modules/FindMayaUsd.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ed4f27a56b..a155a5e3fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,13 @@ else() message(STATUS "UFE not found.") endif() +find_package(MayaUsd OPTIONAL_COMPONENTS) +if(MAYAUSD_FOUND) + message(STATUS "Building with MayaUsd.") +else() + message(STATUS "MayaUsd not used to build.") +endif() + if(CMAKE_WANT_MATERIALX_BUILD AND MAYA_LIGHTAPI_VERSION LESS 2) set(CMAKE_WANT_MATERIALX_BUILD OFF) message(WARNING "Disabling MaterialX VP2 rendering: it is not supported by this version of Maya.") diff --git a/build.py b/build.py index 0f2c96f6d6..2181ce9f27 100755 --- a/build.py +++ b/build.py @@ -556,7 +556,7 @@ def Package(context): help="Directory where Maya is installed.") parser.add_argument("--mayausd-location", type=str, - help="Directory where mayaUSD.mod file is.") + help="Directory where MayaUsd is installed.") parser.add_argument("--pxrusd-location", type=str, help="Directory where Pixar USD is installed.") diff --git a/cmake/modules/FindMayaUsd.cmake b/cmake/modules/FindMayaUsd.cmake new file mode 100644 index 0000000000..99386692b0 --- /dev/null +++ b/cmake/modules/FindMayaUsd.cmake @@ -0,0 +1,89 @@ +# +# Simple module to find MayaUsd. +# +# This module searches for a valid MayaUsd installation. +# It searches for MayaUsd's libraries and include header files. +# +# Variables that will be defined: +# MAYAUSD_FOUND Defined if a MayaUsd installation has been detected +# MAYAUSD_LIBRARY_DIR Path to MayaUsd libraries directory +# MAYAUSD_INCLUDE_DIR Path to the MayaUsd include directory +# MAYAUSDAPI_LIBRARY Path to MayaUsdAPI library +# MAYAUSD_MOD_PATH Path to mayaUSD.mod file +# + +find_path(MAYAUSD_INCLUDE_DIR + mayaUsd/mayaUsd.h + HINTS + ${MAYAUSD_LOCATION} + PATH_SUFFIXES + include/ + DOC + "MayaUsd header path" +) + +find_path(MAYAUSD_LIBRARY_DIR + mayaUsd.lib + HINTS + ${MAYAUSD_LOCATION} + PATH_SUFFIXES + lib/ + DOC + "MayaUsd libraries path" +) + +find_library(MAYAUSDAPI_LIBRARY + NAMES + mayaUsdAPI + HINTS + ${MAYAUSD_LOCATION} + PATHS + ${MAYAUSD_LIBRARY_DIR} + PATH_SUFFIXES + lib/ + DOC + "mayaUsdAPI library" + NO_DEFAULT_PATH +) + +find_path(MAYAUSD_MOD_PATH + mayaUSD.mod + HINTS + ${MAYAUSD_LOCATION} + DOC + "mayaUSD.mod path" +) + + +# Handle the QUIETLY and REQUIRED arguments and set MAYAUSD_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(MAYAUSD + REQUIRED_VARS + MAYAUSD_INCLUDE_DIR + MAYAUSD_LIBRARY_DIR +) + +if(MAYAUSD_FOUND) + message(STATUS "MayaUsd include dir: ${MAYAUSD_INCLUDE_DIR}") + message(STATUS "MayaUsd libraries dir: ${MAYAUSD_LIBRARY_DIR}") + message(STATUS "MayaUsdAPI.lib fullpath : ${MAYAUSDAPI_LIBRARY}") + message(STATUS "MAYAUSD_MOD_PATH : ${MAYAUSD_MOD_PATH}") + + #Add MAYAUSD_MOD_PATH (the path where maya USD .mod file is) to the MAYA_MODULE_PATH + + # Get the current value of the environment variable + set(CURRENT_MAYA_MODULE_PATH $ENV{MAYA_MODULE_PATH}) + + # Append the new path to the current value + set(MAYA_MODULE_PATH "${CURRENT_MAYA_MODULE_PATH}:${MAYAUSD_MOD_PATH}") + + # Export the new value to the environment + set(ENV{MAYA_MODULE_PATH} ${MAYA_MODULE_PATH}) +else() + if(DEFINED MAYAUSD_LOCATION) + message(FATAL_ERROR "Could not find MayaUsd library and include directories in the folder provided : ${MAYAUSD_LOCATION}") + endif() +endif() + diff --git a/doc/build.md b/doc/build.md index 69bb294fcd..76ca86246c 100644 --- a/doc/build.md +++ b/doc/build.md @@ -83,7 +83,7 @@ There are four arguments that must be passed to the script: Optional arguments are : | Flags | Description | |-------------------- |---------------------------------------------------------------------------------------------------- | -| --mayausd-location | directory where the mayaUSD.mod file is. By providing this, you will enable more features for | +| --mayausd-location | directory where MayaUSD is installed. By providing this, you will enable more features for | | | usd stages when using an hydra render delegate, such as : hide/delete the stage when the proxy shape| | | node is hidden/deleted, or applying a transform on the proxy shape node will apply it on the stage. | diff --git a/lib/mayaHydra/hydraExtensions/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/CMakeLists.txt index 7853c33c55..5695d6be9f 100644 --- a/lib/mayaHydra/hydraExtensions/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/CMakeLists.txt @@ -30,29 +30,19 @@ set(HEADERS # ----------------------------------------------------------------------------- # compiler configuration # ----------------------------------------------------------------------------- -if(DEFINED MAYAUSD_LOCATION) - target_compile_definitions(${TARGET_NAME} - PRIVATE - MAYAHYDRALIB_EXPORT - MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD - $<$:OSMac_> - # Copy-pasted from lib/mayaUsd/CMakeLists.txt - ) -else() - target_compile_definitions(${TARGET_NAME} - PRIVATE - MAYAHYDRALIB_EXPORT - $<$:OSMac_> - # Copy-pasted from lib/mayaUsd/CMakeLists.txt - ) -endif() +target_compile_definitions(${TARGET_NAME} + PRIVATE + MAYAHYDRALIB_EXPORT + $<$:MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD> + $<$:OSMac_> + # Copy-pasted from lib/mayaUsd/CMakeLists.txt +) mayaHydra_compile_config(${TARGET_NAME}) # ----------------------------------------------------------------------------- # include directories # ----------------------------------------------------------------------------- -if(DEFINED MAYAUSD_LOCATION) target_include_directories(${TARGET_NAME} PUBLIC ${MAYA_INCLUDE_DIRS} @@ -60,22 +50,10 @@ target_include_directories(${TARGET_NAME} ${PXR_INCLUDE_DIRS} ${BOOST_INCLUDE_DIR} ${CMAKE_BINARY_DIR}/include - ${MAYAUSD_LOCATION}/include PRIVATE $<$:${UFE_INCLUDE_DIR}> + $<$:${MAYAUSD_INCLUDE_DIR}> ) - else() - target_include_directories(${TARGET_NAME} - PUBLIC - ${MAYA_INCLUDE_DIRS} - ${PYTHON_INCLUDE_DIR} - ${PXR_INCLUDE_DIRS} - ${BOOST_INCLUDE_DIR} - ${CMAKE_BINARY_DIR}/include - PRIVATE - $<$:${UFE_INCLUDE_DIR}> - ) - endif() target_compile_definitions(${TARGET_NAME} PUBLIC @@ -113,77 +91,40 @@ if(DEFINED MAYAHYDRA_VERSION) ) endif() - # ----------------------------------------------------------------------------- - # link libraries - # ----------------------------------------------------------------------------- -if(DEFINED MAYAUSD_LOCATION) - find_library(MAYAUSD_API_LIBRARY NAMES mayaUsdAPI PATHS ${MAYAUSD_LOCATION}/lib NO_DEFAULT_PATH) - if(NOT MAYAUSD_API_LIBRARY) - message(WARNING "Could not find mayaUsdAPI library.") - endif() - target_link_libraries(${TARGET_NAME} - PUBLIC - ar - gf - hd - hdx - js - kind - plug - sdf - tf - trace - usd - usdGeom - usdImaging - usdImagingGL - usdLux - usdRender - usdRi - usdShade - usdSkel - usdUtils - ufeExtensions - flowViewport - ${MAYAUSD_API_LIBRARY} - ${MAYA_LIBRARIES} - PRIVATE - $<$:hio> - ${PYTHON_LIBRARIES} - $<$:${UFE_LIBRARY}> - ) -else() - target_link_libraries(${TARGET_NAME} - PUBLIC - ar - gf - hd - hdx - js - kind - plug - sdf - tf - trace - usd - usdGeom - usdImaging - usdImagingGL - usdLux - usdRender - usdRi - usdShade - usdSkel - usdUtils - ufeExtensions - flowViewport - ${MAYA_LIBRARIES} - PRIVATE - $<$:hio> - ${PYTHON_LIBRARIES} - $<$:${UFE_LIBRARY}> - ) -endif() +# ----------------------------------------------------------------------------- +# link libraries +# ----------------------------------------------------------------------------- +target_link_libraries(${TARGET_NAME} + PUBLIC + ar + gf + hd + hdx + js + kind + plug + sdf + tf + trace + usd + usdGeom + usdImaging + usdImagingGL + usdLux + usdRender + usdRi + usdShade + usdSkel + usdUtils + ufeExtensions + flowViewport + ${MAYA_LIBRARIES} + PRIVATE + $<$:hio> + ${PYTHON_LIBRARIES} + $<$:${UFE_LIBRARY}> + $<$:${MAYAUSDAPI_LIBRARY}> +) # ----------------------------------------------------------------------------- # promoted headers diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp index b938971429..bc6acdad5f 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp @@ -68,7 +68,7 @@ void MayaUsdProxyShapeSceneIndex::onTimeChanged(void* data) void MayaUsdProxyShapeSceneIndex::UpdateTime() { - if (_usdImagingStageSceneIndex && _proxyStage.isValid() && _dagNodeHandle.isValid()) { + if (_usdImagingStageSceneIndex && _dagNodeHandle.isValid()) { _usdImagingStageSceneIndex->SetTime(_proxyStage.getTime());//We have the possibility to scale and offset the time in _proxyShapeBase } } @@ -92,7 +92,7 @@ void MayaUsdProxyShapeSceneIndex::_PopulateAndApplyPendingChanges() void MayaUsdProxyShapeSceneIndex::Populate() { - if (!_populated && _proxyStage.isValid()) { + if (!_populated) { auto stage = _proxyStage.getUsdStage(); // Check whether the pseudo-root has children if (stage && (!stage->GetPseudoRoot().GetChildren().empty())) { diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp index d59f89c104..0b3471990b 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp @@ -207,82 +207,80 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) { //We receive only dag nodes of type MayaUsdProxyShapeNode MAYAUSDAPI_NS::ProxyStage proxyStage(dagNode); - if (TF_VERIFY(proxyStage.isValid(), "Error getting MayaUsdAPIProxyStage")) { - MayaHydraSceneIndexRegistrationPtr registration(new MayaHydraSceneIndexRegistration()); + MayaHydraSceneIndexRegistrationPtr registration(new MayaHydraSceneIndexRegistration()); - //Add the usdimaging stage scene index chain as a data producer scene index in flow viewport + //Add the usdimaging stage scene index chain as a data producer scene index in flow viewport - //Since we want to insert a parent primitive for the stage scene index to be transformed or set visible/invisible, we need to set this scene indices chain - //before some of the instancing scene indices for UsdImaginsStageSceneIndex, and there is a slot for that purpose which is createInfo.overridesSceneIndexCallback - //With this callback you can insert some scene indices which will be applied before the prototype scene indices. - //This will be done inside Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex later - UsdImagingCreateSceneIndicesInfo createInfo; + //Since we want to insert a parent primitive for the stage scene index to be transformed or set visible/invisible, we need to set this scene indices chain + //before some of the instancing scene indices for UsdImaginsStageSceneIndex, and there is a slot for that purpose which is createInfo.overridesSceneIndexCallback + //With this callback you can insert some scene indices which will be applied before the prototype scene indices. + //This will be done inside Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex later + UsdImagingCreateSceneIndicesInfo createInfo; - auto stage = proxyStage.getUsdStage(); - // Check whether the pseudo-root has children - if (stage && (!stage->GetPseudoRoot().GetChildren().empty())) { - createInfo.stage = stage;//Add the stage to the creation parameters - } + auto stage = proxyStage.getUsdStage(); + // Check whether the pseudo-root has children + if (stage && (!stage->GetPseudoRoot().GetChildren().empty())) { + createInfo.stage = stage;//Add the stage to the creation parameters + } - MStatus status; - MDagPath dagPath(MDagPath::getAPathTo(dagNode, &status)); - if (TF_VERIFY(status == MS::kSuccess, "Incapable of finding dag path to given node")) { - registration->dagNode = MObjectHandle(dagNode); - // Construct the scene index path prefix appended to each rprim created by it. - // It is composed of the "scene index plugin's name" + "dag node name" + - // "disambiguator" The dag node name disambiguator is necessary in situation - // where node name isn't unique and may clash with other node defined by the - // same plugin. - MFnDependencyNode dependNodeFn(dagNode); - std::string dependNodeNameString (dependNodeFn.name().asChar()); - SanitizeNameForSdfPath(dependNodeNameString); + MStatus status; + MDagPath dagPath(MDagPath::getAPathTo(dagNode, &status)); + if (TF_VERIFY(status == MS::kSuccess, "Incapable of finding dag path to given node")) { + registration->dagNode = MObjectHandle(dagNode); + // Construct the scene index path prefix appended to each rprim created by it. + // It is composed of the "scene index plugin's name" + "dag node name" + + // "disambiguator" The dag node name disambiguator is necessary in situation + // where node name isn't unique and may clash with other node defined by the + // same plugin. + MFnDependencyNode dependNodeFn(dagNode); + std::string dependNodeNameString (dependNodeFn.name().asChar()); + SanitizeNameForSdfPath(dependNodeNameString); - registration->sceneIndexPathPrefix = - SdfPath::AbsoluteRootPath() - .AppendPath(SdfPath(dependNodeNameString - + (dependNodeFn.hasUniqueName() - ? "" - : "__" + std::to_string(_incrementedCounterDisambiguator++)))); - - - //We will get the following scene indices from Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex - HdSceneIndexBaseRefPtr finalSceneIndex = nullptr; - UsdImagingStageSceneIndexRefPtr stageSceneIndex = nullptr; - - PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = - Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex(createInfo, finalSceneIndex, stageSceneIndex, - registration->sceneIndexPathPrefix, (void*)&dagNode); - if (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex){ - TF_CODING_ERROR("Error (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex) !"); - } + registration->sceneIndexPathPrefix = + SdfPath::AbsoluteRootPath() + .AppendPath(SdfPath(dependNodeNameString + + (dependNodeFn.hasUniqueName() + ? "" + : "__" + std::to_string(_incrementedCounterDisambiguator++)))); + + + //We will get the following scene indices from Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex + HdSceneIndexBaseRefPtr finalSceneIndex = nullptr; + UsdImagingStageSceneIndexRefPtr stageSceneIndex = nullptr; + + PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = + Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageSceneIndex(createInfo, finalSceneIndex, stageSceneIndex, + registration->sceneIndexPathPrefix, (void*)&dagNode); + if (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex){ + TF_CODING_ERROR("Error (nullptr == dataProducerSceneIndexData || nullptr == finalSceneIndex || nullptr == stageSceneIndex) !"); + } - //Create maya usd proxy shape scene index, since this scene index contains maya data, it cannot be added by the flow viewport API - auto mayaUsdProxyShapeSceneIndex = MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::New(proxyStage, finalSceneIndex, stageSceneIndex, MObjectHandle(dagNode)); - registration->pluginSceneIndex = mayaUsdProxyShapeSceneIndex; - registration->interpretRprimPathFn = &(MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::InterpretRprimPath); - mayaUsdProxyShapeSceneIndex->Populate(); - - registration->rootSceneIndex = registration->pluginSceneIndex; - - //Add the PathInterfaceSceneIndex which must be the last scene index, it is used for selection highlighting - registration->rootSceneIndex = PathInterfaceSceneIndex::New( - registration->rootSceneIndex, - registration->sceneIndexPathPrefix); - - //Set the chain back into the dataProducerSceneIndexData in both members - dataProducerSceneIndexData->SetDataProducerSceneIndex(registration->rootSceneIndex); - dataProducerSceneIndexData->SetDataProducerLastSceneIndexChain(registration->rootSceneIndex); - - //Add this chain scene index to the render index proxy from all viewports - const bool bRes = Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageDataProducerSceneIndexDataBaseToAllViewports(dataProducerSceneIndexData); - if (false == bRes){ - TF_CODING_ERROR("Fvp::DataProducerSceneIndexInterfaceImp::get().addDataProducerSceneIndex returned false !"); - } - - // Add registration record if everything succeeded - _registrations.insert({ registration->sceneIndexPathPrefix, registration }); - _registrationsByObjectHandle.insert({ registration->dagNode, registration }); + //Create maya usd proxy shape scene index, since this scene index contains maya data, it cannot be added by the flow viewport API + auto mayaUsdProxyShapeSceneIndex = MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::New(proxyStage, finalSceneIndex, stageSceneIndex, MObjectHandle(dagNode)); + registration->pluginSceneIndex = mayaUsdProxyShapeSceneIndex; + registration->interpretRprimPathFn = &(MAYAHYDRA_NS_DEF::MayaUsdProxyShapeSceneIndex::InterpretRprimPath); + mayaUsdProxyShapeSceneIndex->Populate(); + + registration->rootSceneIndex = registration->pluginSceneIndex; + + //Add the PathInterfaceSceneIndex which must be the last scene index, it is used for selection highlighting + registration->rootSceneIndex = PathInterfaceSceneIndex::New( + registration->rootSceneIndex, + registration->sceneIndexPathPrefix); + + //Set the chain back into the dataProducerSceneIndexData in both members + dataProducerSceneIndexData->SetDataProducerSceneIndex(registration->rootSceneIndex); + dataProducerSceneIndexData->SetDataProducerLastSceneIndexChain(registration->rootSceneIndex); + + //Add this chain scene index to the render index proxy from all viewports + const bool bRes = Fvp::DataProducerSceneIndexInterfaceImp::get().addUsdStageDataProducerSceneIndexDataBaseToAllViewports(dataProducerSceneIndexData); + if (false == bRes){ + TF_CODING_ERROR("Fvp::DataProducerSceneIndexInterfaceImp::get().addDataProducerSceneIndex returned false !"); } + + // Add registration record if everything succeeded + _registrations.insert({ registration->sceneIndexPathPrefix, registration }); + _registrationsByObjectHandle.insert({ registration->dagNode, registration }); } } #else From cdec922535a474b6adbc8d4954ecc27c823c0fde Mon Sep 17 00:00:00 2001 From: David Lanier Date: Fri, 19 Jan 2024 11:24:35 +0100 Subject: [PATCH 03/25] HYDRA-691 : Modifications from code review --- lib/mayaHydra/hydraExtensions/CMakeLists.txt | 2 +- .../hydraExtensions/sceneIndex/CMakeLists.txt | 4 +- ....cpp => mhMayaUsdProxyShapeSceneIndex.cpp} | 8 +- ...ndex.h => mhMayaUsdProxyShapeSceneIndex.h} | 6 +- .../sceneIndex/registration.cpp | 8 +- lib/mayaHydra/mayaPlugin/renderOverride.cpp | 32 +-- .../mayaUsd/render/mayaToHydra/CMakeLists.txt | 1 + .../mayaUsdAPI_DirectionalLight.png | Bin 0 -> 7163 bytes .../mayaUsdAPI_TransformMoved.png | Bin 0 -> 7111 bytes .../mayaUsdAPI__NodeDeleted.png | Bin 0 -> 3179 bytes .../mayaUsdAPI__NodeDeletedRedo.png | Bin 0 -> 3179 bytes .../mayaUsdAPI__NodeDeletedUndo.png | Bin 0 -> 7111 bytes .../mayaUsdAPI__NodeDeletedUndoAgain.png | Bin 0 -> 7111 bytes .../mayaUsdAPI__NodeHidden.png | Bin 0 -> 3179 bytes ...aUsdAPI__NodeMovedAfterDeletionAndUndo.png | Bin 0 -> 4381 bytes .../mayaUsdAPI__NodeUnhidden.png | Bin 0 -> 7111 bytes .../mayaUsdAPI__VP2AndThenBackToStorm.png | Bin 0 -> 4381 bytes .../render/mayaToHydra/testMayaUsdAPIUsage.py | 90 +++++++ .../UsdStageWithSphereMatXStdSurf.ma | 244 ++++++++++++++++++ .../UsdStageWithSphereMatXStdSurf.usd | Bin 0 -> 1230 bytes 20 files changed, 354 insertions(+), 41 deletions(-) rename lib/mayaHydra/hydraExtensions/sceneIndex/{mayaHydraMayaUsdProxyShapeSceneIndex.cpp => mhMayaUsdProxyShapeSceneIndex.cpp} (95%) rename lib/mayaHydra/hydraExtensions/sceneIndex/{mayaHydraMayaUsdProxyShapeSceneIndex.h => mhMayaUsdProxyShapeSceneIndex.h} (96%) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_DirectionalLight.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_TransformMoved.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeleted.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedRedo.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndo.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndoAgain.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeHidden.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeMovedAfterDeletionAndUndo.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeUnhidden.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__VP2AndThenBackToStorm.png create mode 100644 test/lib/mayaUsd/render/mayaToHydra/testMayaUsdAPIUsage.py create mode 100644 test/testSamples/testMayaUsdAPIUsage/UsdStageWithSphereMatXStdSurf.ma create mode 100644 test/testSamples/testMayaUsdAPIUsage/UsdStageWithSphereMatXStdSurf.usd diff --git a/lib/mayaHydra/hydraExtensions/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/CMakeLists.txt index 5695d6be9f..f8da1bc7cd 100644 --- a/lib/mayaHydra/hydraExtensions/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/CMakeLists.txt @@ -33,7 +33,7 @@ set(HEADERS target_compile_definitions(${TARGET_NAME} PRIVATE MAYAHYDRALIB_EXPORT - $<$:MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD> + $<$:MAYAHYDRALIB_MAYAUSD_ENABLED> $<$:OSMac_> # Copy-pasted from lib/mayaUsd/CMakeLists.txt ) diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt index 38ed2f1725..366b9c1115 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/CMakeLists.txt @@ -16,7 +16,7 @@ target_sources(${TARGET_NAME} mayaHydraSceneIndexDataFactoriesSetup.cpp mayaHydraMayaFilteringSceneIndexData.cpp mayaHydraMayaFilteringSceneIndexDataConcreteFactory.cpp - mayaHydraMayaUsdProxyShapeSceneIndex.cpp + mhMayaUsdProxyShapeSceneIndex.cpp ) set(HEADERS @@ -33,7 +33,7 @@ set(HEADERS mayaHydraSceneIndexDataFactoriesSetup.h mayaHydraMayaFilteringSceneIndexData.h mayaHydraMayaFilteringSceneIndexDataConcreteFactory.h - mayaHydraMayaUsdProxyShapeSceneIndex.h + mhMayaUsdProxyShapeSceneIndex.h ) # ----------------------------------------------------------------------------- diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp similarity index 95% rename from lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp rename to lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp index bc6acdad5f..6d6ab196fd 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.cpp @@ -14,9 +14,9 @@ // limitations under the License. // -#include "mayaHydraMayaUsdProxyShapeSceneIndex.h" +#include "mhMayaUsdProxyShapeSceneIndex.h" -#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) +#if defined(MAYAHYDRALIB_MAYAUSD_ENABLED) //Maya headers #include //For timeChanged callback @@ -108,7 +108,7 @@ Ufe::Path MayaUsdProxyShapeSceneIndex::InterpretRprimPath( const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& path) { - if (MayaUsdProxyShapeSceneIndexRefPtr proxyShapeSceneIndex = TfStatic_cast(sceneIndex)) { + if (MayaUsdProxyShapeSceneIndexRefPtr proxyShapeSceneIndex = TfDynamic_cast(sceneIndex)) { MDagPath dagPath(MDagPath::getAPathTo(proxyShapeSceneIndex->_dagNodeHandle.object())); return Ufe::Path( { UfeExtensions::dagPathToUfePathSegment(dagPath), UfeExtensions::sdfPathToUfePathSegment(path, UfeExtensions::getUsdRunTimeId()) }); @@ -131,4 +131,4 @@ SdfPathVector MayaUsdProxyShapeSceneIndex::GetChildPrimPaths(const SdfPath& prim } // namespace MAYAUSD_NS_DEF PXR_NAMESPACE_CLOSE_SCOPE -#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD +#endif //MAYAHYDRALIB_MAYAUSD_ENABLED diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.h similarity index 96% rename from lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h rename to lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.h index 90b0f8beb5..74d5248a60 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mhMayaUsdProxyShapeSceneIndex.h @@ -16,7 +16,7 @@ #ifndef MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H #define MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H -#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) +#if defined(MAYAHYDRALIB_MAYAUSD_ENABLED) //MayaHydra headers #include "mayaHydraLib/api.h" #include "mayaHydraLib/mayaHydra.h" @@ -33,7 +33,7 @@ //Maya headers #include -#include +#include //Ufe headers #include @@ -106,6 +106,6 @@ class MayaUsdProxyShapeSceneIndex : public HdSingleInputFilteringSceneIndexBase PXR_NAMESPACE_CLOSE_SCOPE -#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD +#endif //MAYAHYDRALIB_MAYAUSD_ENABLED #endif //MAYA_HYDRA_MAYAUSD_PROXY_SHAPE_SCENE_INDEX_PLUGIN_H \ No newline at end of file diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp index 0b3471990b..17981f893e 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp @@ -16,7 +16,7 @@ #include "mayaHydraLib/hydraUtils.h" #include "mayaHydraLib/sceneIndex/registration.h" -#include "mayaHydraLib/sceneIndex/mayaHydraMayaUsdProxyShapeSceneIndex.h" +#include "mayaHydraLib/sceneIndex/mhMayaUsdProxyShapeSceneIndex.h" #include #include @@ -30,7 +30,7 @@ #include #include -#if defined(MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD) +#if defined(MAYAHYDRALIB_MAYAUSD_ENABLED) #include #endif @@ -202,7 +202,7 @@ bool MayaHydraSceneIndexRegistry::_RemoveSceneIndexForNode(const MObject& dagNod return false; } -#ifdef MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD +#ifdef MAYAHYDRALIB_MAYAUSD_ENABLED void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) { //We receive only dag nodes of type MayaUsdProxyShapeNode @@ -380,7 +380,7 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) } } } -#endif //MAYAHYDRALIB_MAYAUSD_IS_USED_TO_BUILD +#endif //MAYAHYDRALIB_MAYAUSD_ENABLED void MayaHydraSceneIndexRegistry::_SceneIndexNodeAddedCallback(MObject& dagNode, void* clientData) { diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.cpp b/lib/mayaHydra/mayaPlugin/renderOverride.cpp index 9d77715bad..0d90aba83d 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.cpp +++ b/lib/mayaHydra/mayaPlugin/renderOverride.cpp @@ -59,21 +59,6 @@ #include -namespace MayaUsd { -// hash combiner taken from: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0814r0.pdf - -// boost::hash implementation also relies on the same algorithm: -// https://www.boost.org/doc/libs/1_64_0/boost/functional/hash/hash.hpp - -template inline void hash_combine(std::size_t& seed, const T& value) -{ - ::std::hash hasher; - seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); -} -} // namespace MayaUsd - - #include #include #include @@ -1101,22 +1086,15 @@ void MtohRenderOverride::_PopulateSelectionList( // respect to current scene index. This is because the scene index was inserted // into the render index using a custom prefix. As a result the scene index // prefix will be prepended to rprims tied to that scene index automatically. - const std::string& sceneIndexPathPrefixAsString = registration->sceneIndexPathPrefix.GetString(); - const std::string& pickedPathAsString = pickedPath.GetString(); - std::string localPathAsString; - const size_t foundPlace = pickedPathAsString.find(sceneIndexPathPrefixAsString); - if (foundPlace == std::string::npos) { + const SdfPath& sceneIndexPathPrefix = registration->sceneIndexPathPrefix; + if ( ! pickedPath.HasPrefix(sceneIndexPathPrefix)){ TF_CODING_ERROR("pickedPathAsString.find(sceneIndexPathPrefixAsString) returned std::string::npos !"); return; } - - //Keep only the right part of the string after the prefix - const size_t placeToKeep = foundPlace + sceneIndexPathPrefixAsString.length(); - localPathAsString = pickedPathAsString.substr(placeToKeep, pickedPathAsString.length() - placeToKeep); - - const SdfPath localPath(localPathAsString); + const SdfPath relativePath = pickedPath.MakeRelativePath(sceneIndexPathPrefix); + Ufe::Path interpretedPath(registration->interpretRprimPathFn( - registration->pluginSceneIndex, localPath)); + registration->pluginSceneIndex, relativePath)); // If this is a maya UFE path, then select using MSelectionList // This is because the NamedSelection ignores Ufe items made from maya ufe path diff --git a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt index 94f297ff34..51d007cb33 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt @@ -14,6 +14,7 @@ set(TEST_SCRIPT_FILES testNewSceneWithStage.py testDirectionalLights.py testFlowViewportAPI.py + testMayaUsdAPIUsage.py cpp/testColorPreferences.py cpp/testCppFramework.py cpp/testMayaSceneFlattening.py diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_DirectionalLight.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_DirectionalLight.png new file mode 100644 index 0000000000000000000000000000000000000000..fd5ce14bca88a71916b9585c1cbed0579245dbc9 GIT binary patch literal 7163 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_TransformMoved.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI_TransformMoved.png new file mode 100644 index 0000000000000000000000000000000000000000..44f7daf2ceaf3133b05d5953cdd9736430b102b4 GIT binary patch literal 7111 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeleted.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeleted.png new file mode 100644 index 0000000000000000000000000000000000000000..3ceaa2702b4c879c63426b2bf3a62a7b82ea77fd GIT binary patch literal 3179 zcmeHKS6EZo7Ct9bLkTd0BcUW31tnlXaTEf?8H8Yo6+$t96cG?Y2}mc%d?;Rl2#5nR z;JpEri3v&(2z5jaiiIK|kN{(h1R^Mq0153L(EE7beVB){_d5UHd#$zq^*^kgew^s2 z0Y}0C0MKwE*q;OdkiPnjWSL*yE; zIt-XTdJO<-V@~!5PRA5Z@Xu!Q2!_x8_Uqr>vPFy3cIk=X{LYJKYt>M-3Obuf_%l9p z>Spb^qHF_h_e4@X^TN$y$E&#KMB}BhWRH~!rd?A*LjpjHPppxu0VBUFD$=gd04;4T zU=s|6x5oolR8;|O5JYc61NQ$ce$OP(H5TW)xu_TAEH9N7jG~{yihS;3a*|rx-LF7N zC1-k`Pgz;Gnc)R*`L$_Su2lGHcx8&2ygY@lTS*f4fnT;_>6wRcLoP<;%`)kZ;+iCL zAWMf%yvC+=suE261!r)y>#78mEk^zq{HaRUo*2jZ`ctLr>3uitmPQ4=zBy4#nfnS0toO=r-loT(ax24tWW`n!!Y72KvSEPO2B? z&~W#-PW8c`KNTbooXzsMnlht9SCPaR`A)!n0ugt(=1*H<*R?6Q+hv7+76l>o7}(pE z;5zBo4NWS(R3!--onn*0&YSgy_%Tx4+#!GTF5ZD8?2{}&fT!XIVk2?Dk^`G1;wL-A zCH#p0*#eEYWixJesm%t+>Cd2B8Fa7UH{Aupwil>M7Y^WE+$$|&p4c#$t0x{Aqp^~G zfqf$QJ|tN8mk92iFW^x`;a#D1NHXZ?s}ymNn-g9BtW^YmhXG?9%LRve6<>V&fmj*k z(i`TiR?F~CA9U-OD&f~Vl5F-$!CozTev!!p8z&x*k_WJg9YNQ__;Yc8RK;VDAHMa$ zrf3Z?hJgCnl)q%pV#R&RVF<8J6duss$Y74m>5;*B4EiV5=L;4bm;(lll3%;Lrj)kJ zvx1EbthfDL1VKF2G0>>Xz>b_J8qz%(Ob_jy99X94Ef|>CH90VNDT7VJScTx-i>rbm zK~3g@V^L?)J9T$foJzWVTAUM&(j!+JF+p7WmA~0APV|;ajVYX{|JtSLqR<#P|y>FKEL${ zz82-R-#oN$)YM3ie1qAk8)o0CQX;*M&br2SAJ$gx=<2}SH!_*X3%24^dUiLed7 zIs5cwjYUW(rIqaawzLz5R%lih)=fWU&Vgj!s{Ek(SLh;;$Tx+BP=%4UwCjd@*GSX{ zA#e9J^|YWE6NVOOn>C%*PKK@eV|VJdSY3t_#CJIvY@pZrG(OINR1rWp*KdIW8+X0wXL z&#{w&e<4y~=L2eKZjj zLKs&Uk7~uKoOCg?Tb4|<_m(S+n5DU;{J8fODAzMZ0}{;l+(-P=`h8FR@3P7r4Ii_D XBa%;0@Bjbb2!PW;qCNW;?@Rv$;gqYq literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedRedo.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedRedo.png new file mode 100644 index 0000000000000000000000000000000000000000..3ceaa2702b4c879c63426b2bf3a62a7b82ea77fd GIT binary patch literal 3179 zcmeHKS6EZo7Ct9bLkTd0BcUW31tnlXaTEf?8H8Yo6+$t96cG?Y2}mc%d?;Rl2#5nR z;JpEri3v&(2z5jaiiIK|kN{(h1R^Mq0153L(EE7beVB){_d5UHd#$zq^*^kgew^s2 z0Y}0C0MKwE*q;OdkiPnjWSL*yE; zIt-XTdJO<-V@~!5PRA5Z@Xu!Q2!_x8_Uqr>vPFy3cIk=X{LYJKYt>M-3Obuf_%l9p z>Spb^qHF_h_e4@X^TN$y$E&#KMB}BhWRH~!rd?A*LjpjHPppxu0VBUFD$=gd04;4T zU=s|6x5oolR8;|O5JYc61NQ$ce$OP(H5TW)xu_TAEH9N7jG~{yihS;3a*|rx-LF7N zC1-k`Pgz;Gnc)R*`L$_Su2lGHcx8&2ygY@lTS*f4fnT;_>6wRcLoP<;%`)kZ;+iCL zAWMf%yvC+=suE261!r)y>#78mEk^zq{HaRUo*2jZ`ctLr>3uitmPQ4=zBy4#nfnS0toO=r-loT(ax24tWW`n!!Y72KvSEPO2B? z&~W#-PW8c`KNTbooXzsMnlht9SCPaR`A)!n0ugt(=1*H<*R?6Q+hv7+76l>o7}(pE z;5zBo4NWS(R3!--onn*0&YSgy_%Tx4+#!GTF5ZD8?2{}&fT!XIVk2?Dk^`G1;wL-A zCH#p0*#eEYWixJesm%t+>Cd2B8Fa7UH{Aupwil>M7Y^WE+$$|&p4c#$t0x{Aqp^~G zfqf$QJ|tN8mk92iFW^x`;a#D1NHXZ?s}ymNn-g9BtW^YmhXG?9%LRve6<>V&fmj*k z(i`TiR?F~CA9U-OD&f~Vl5F-$!CozTev!!p8z&x*k_WJg9YNQ__;Yc8RK;VDAHMa$ zrf3Z?hJgCnl)q%pV#R&RVF<8J6duss$Y74m>5;*B4EiV5=L;4bm;(lll3%;Lrj)kJ zvx1EbthfDL1VKF2G0>>Xz>b_J8qz%(Ob_jy99X94Ef|>CH90VNDT7VJScTx-i>rbm zK~3g@V^L?)J9T$foJzWVTAUM&(j!+JF+p7WmA~0APV|;ajVYX{|JtSLqR<#P|y>FKEL${ zz82-R-#oN$)YM3ie1qAk8)o0CQX;*M&br2SAJ$gx=<2}SH!_*X3%24^dUiLed7 zIs5cwjYUW(rIqaawzLz5R%lih)=fWU&Vgj!s{Ek(SLh;;$Tx+BP=%4UwCjd@*GSX{ zA#e9J^|YWE6NVOOn>C%*PKK@eV|VJdSY3t_#CJIvY@pZrG(OINR1rWp*KdIW8+X0wXL z&#{w&e<4y~=L2eKZjj zLKs&Uk7~uKoOCg?Tb4|<_m(S+n5DU;{J8fODAzMZ0}{;l+(-P=`h8FR@3P7r4Ii_D XBa%;0@Bjbb2!PW;qCNW;?@Rv$;gqYq literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndo.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndo.png new file mode 100644 index 0000000000000000000000000000000000000000..44f7daf2ceaf3133b05d5953cdd9736430b102b4 GIT binary patch literal 7111 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndoAgain.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeDeletedUndoAgain.png new file mode 100644 index 0000000000000000000000000000000000000000..44f7daf2ceaf3133b05d5953cdd9736430b102b4 GIT binary patch literal 7111 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeHidden.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeHidden.png new file mode 100644 index 0000000000000000000000000000000000000000..3ceaa2702b4c879c63426b2bf3a62a7b82ea77fd GIT binary patch literal 3179 zcmeHKS6EZo7Ct9bLkTd0BcUW31tnlXaTEf?8H8Yo6+$t96cG?Y2}mc%d?;Rl2#5nR z;JpEri3v&(2z5jaiiIK|kN{(h1R^Mq0153L(EE7beVB){_d5UHd#$zq^*^kgew^s2 z0Y}0C0MKwE*q;OdkiPnjWSL*yE; zIt-XTdJO<-V@~!5PRA5Z@Xu!Q2!_x8_Uqr>vPFy3cIk=X{LYJKYt>M-3Obuf_%l9p z>Spb^qHF_h_e4@X^TN$y$E&#KMB}BhWRH~!rd?A*LjpjHPppxu0VBUFD$=gd04;4T zU=s|6x5oolR8;|O5JYc61NQ$ce$OP(H5TW)xu_TAEH9N7jG~{yihS;3a*|rx-LF7N zC1-k`Pgz;Gnc)R*`L$_Su2lGHcx8&2ygY@lTS*f4fnT;_>6wRcLoP<;%`)kZ;+iCL zAWMf%yvC+=suE261!r)y>#78mEk^zq{HaRUo*2jZ`ctLr>3uitmPQ4=zBy4#nfnS0toO=r-loT(ax24tWW`n!!Y72KvSEPO2B? z&~W#-PW8c`KNTbooXzsMnlht9SCPaR`A)!n0ugt(=1*H<*R?6Q+hv7+76l>o7}(pE z;5zBo4NWS(R3!--onn*0&YSgy_%Tx4+#!GTF5ZD8?2{}&fT!XIVk2?Dk^`G1;wL-A zCH#p0*#eEYWixJesm%t+>Cd2B8Fa7UH{Aupwil>M7Y^WE+$$|&p4c#$t0x{Aqp^~G zfqf$QJ|tN8mk92iFW^x`;a#D1NHXZ?s}ymNn-g9BtW^YmhXG?9%LRve6<>V&fmj*k z(i`TiR?F~CA9U-OD&f~Vl5F-$!CozTev!!p8z&x*k_WJg9YNQ__;Yc8RK;VDAHMa$ zrf3Z?hJgCnl)q%pV#R&RVF<8J6duss$Y74m>5;*B4EiV5=L;4bm;(lll3%;Lrj)kJ zvx1EbthfDL1VKF2G0>>Xz>b_J8qz%(Ob_jy99X94Ef|>CH90VNDT7VJScTx-i>rbm zK~3g@V^L?)J9T$foJzWVTAUM&(j!+JF+p7WmA~0APV|;ajVYX{|JtSLqR<#P|y>FKEL${ zz82-R-#oN$)YM3ie1qAk8)o0CQX;*M&br2SAJ$gx=<2}SH!_*X3%24^dUiLed7 zIs5cwjYUW(rIqaawzLz5R%lih)=fWU&Vgj!s{Ek(SLh;;$Tx+BP=%4UwCjd@*GSX{ zA#e9J^|YWE6NVOOn>C%*PKK@eV|VJdSY3t_#CJIvY@pZrG(OINR1rWp*KdIW8+X0wXL z&#{w&e<4y~=L2eKZjj zLKs&Uk7~uKoOCg?Tb4|<_m(S+n5DU;{J8fODAzMZ0}{;l+(-P=`h8FR@3P7r4Ii_D XBa%;0@Bjbb2!PW;qCNW;?@Rv$;gqYq literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeMovedAfterDeletionAndUndo.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__NodeMovedAfterDeletionAndUndo.png new file mode 100644 index 0000000000000000000000000000000000000000..9dbfeda9774897b88018e7fb840d5078f1848b65 GIT binary patch literal 4381 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

|f=4RwY%Y9hZF%M?>y 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 literal 0 HcmV?d00001 diff --git a/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__VP2AndThenBackToStorm.png b/test/lib/mayaUsd/render/mayaToHydra/MayaUsdAPIUsageTest/mayaUsdAPI__VP2AndThenBackToStorm.png new file mode 100644 index 0000000000000000000000000000000000000000..9dbfeda9774897b88018e7fb840d5078f1848b65 GIT binary patch literal 4381 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

|f=4RwY%Y9hZF%M?>y zDf``d@tIvhUtLOK_*a{475Po1;(k)#oAaL-p=;4>4K*a6LK~dUFlZH*K#h|ZsinNn z#xnC!;r%ci_@_zgJv;21SV|^u7{ySCl5Sbv%SI>Ow92pdO52`%Rn*ftCS&E zzrLZudBrgyJI(zzrueOl_EW;W>v(txSx_g_Js=0yDmeJT4?UApGfa-_Q|cZ7TS@qQ zwT8PP2Xh9vsup5fA_KE1+3`Gc*tO{RF_G%N<2g9m`jo`E-mmMn