From 9922683e39dbe649f8f8021f56c349f2271e9fe1 Mon Sep 17 00:00:00 2001 From: David Lanier <122012029+lanierd-adsk@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:12:56 +0100 Subject: [PATCH] HYDRA-598 : Merge viewport information interface (#4) * HYDRA-598 : Merge viewport information interface * Fix build under Linux. * HYDRA-598 : Fixes from code review. * HYDRA-598 : Attempt in fixing Linux crash in tests * HYDRA-598 : Changes from code review. * HYDRA-598 : Fix a possible crash by deleting the RenderIndexProxy last. * HYDRA-598 : Fixes from the code review. * HYDRA-598 : Update a name from code review. * HYDRA-598 : Add tests for multiviewports and update code taking into account the shared scene/render/index we use for all viewports * HYDRA-598 : Fixes from code review. * HYDRA-598 : Fixes from code review. --- lib/flowViewport/API/CMakeLists.txt | 3 + lib/flowViewport/API/fvpInformationClient.h | 63 +++++++++ .../API/fvpInformationInterface.h | 98 ++++++++++++++ lib/flowViewport/API/fvpSelectionClient.h | 2 +- .../API/interfacesImp/CMakeLists.txt | 2 + .../fvpInformationInterfaceImp.cpp | 100 +++++++++++++++ .../fvpInformationInterfaceImp.h | 50 ++++++++ .../fvpSelectionInterfaceImp.cpp | 7 +- .../interfacesImp/fvpSelectionInterfaceImp.h | 4 +- .../CMakeLists.txt | 31 +++++ ...ormationAndSceneIndicesPerViewportData.cpp | 40 ++++++ ...nformationAndSceneIndicesPerViewportData.h | 67 ++++++++++ ...nAndSceneIndicesPerViewportDataManager.cpp | 110 ++++++++++++++++ ...ionAndSceneIndicesPerViewportDataManager.h | 61 +++++++++ lib/flowViewport/API/samples/CMakeLists.txt | 2 + .../samples/fvpInformationClientExample.cpp | 39 ++++++ .../API/samples/fvpInformationClientExample.h | 73 +++++++++++ lib/flowViewport/sceneIndex/CMakeLists.txt | 1 + .../sceneIndex/fvpRenderIndexProxy.cpp | 30 ++++- .../sceneIndex/fvpRenderIndexProxy.h | 19 ++- .../sceneIndex/fvpRenderIndexProxyFwd.h | 28 ++++ lib/mayaHydra/hydraExtensions/CMakeLists.txt | 6 +- .../adapters/cameraAdapter.cpp | 2 +- .../adapters/materialAdapter.cpp | 2 +- .../hydraExtensions/adapters/shapeAdapter.cpp | 2 +- .../hydraExtensions/delegates/delegate.h | 8 ++ lib/mayaHydra/hydraExtensions/hydraUtils.cpp | 10 +- .../{interface.h => mayaHydraLibInterface.h} | 11 +- ...ceImp.cpp => mayaHydraLibInterfaceImp.cpp} | 15 ++- ...erfaceImp.h => mayaHydraLibInterfaceImp.h} | 14 +- .../mayaHydraSceneProducer.cpp | 13 +- .../hydraExtensions/mayaHydraSceneProducer.h | 5 +- .../sceneIndex/mayaHydraSceneIndex.cpp | 25 +++- .../sceneIndex/mayaHydraSceneIndex.h | 9 ++ .../sceneIndex/registration.cpp | 8 +- .../hydraExtensions/sceneIndex/registration.h | 4 +- lib/mayaHydra/mayaPlugin/renderOverride.cpp | 99 +++++++++++---- lib/mayaHydra/mayaPlugin/renderOverride.h | 8 +- .../mayaHydraSceneBrowser.cpp | 2 +- .../mayaHydraSceneBrowserTestCmd.cpp | 2 +- .../mayaUsd/render/mayaToHydra/CMakeLists.txt | 1 + .../render/mayaToHydra/cpp/CMakeLists.txt | 2 + .../render/mayaToHydra/cpp/infoClientTest.h | 51 ++++++++ .../testFlowViewportAPIViewportInformation.py | 72 +++++++++++ ...vpViewportInformationMultipleViewports.cpp | 120 ++++++++++++++++++ ...vpViewportInformationRendererSwitching.cpp | 104 +++++++++++++++ .../render/mayaToHydra/cpp/testUtils.cpp | 2 +- 47 files changed, 1341 insertions(+), 86 deletions(-) create mode 100644 lib/flowViewport/API/fvpInformationClient.h create mode 100644 lib/flowViewport/API/fvpInformationInterface.h create mode 100644 lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.cpp create mode 100644 lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h create mode 100644 lib/flowViewport/API/perViewportSceneIndicesData/CMakeLists.txt create mode 100644 lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp create mode 100644 lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.h create mode 100644 lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.cpp create mode 100644 lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h create mode 100644 lib/flowViewport/API/samples/fvpInformationClientExample.cpp create mode 100644 lib/flowViewport/API/samples/fvpInformationClientExample.h create mode 100644 lib/flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h rename lib/mayaHydra/hydraExtensions/{interface.h => mayaHydraLibInterface.h} (81%) rename lib/mayaHydra/hydraExtensions/{interfaceImp.cpp => mayaHydraLibInterfaceImp.cpp} (76%) rename lib/mayaHydra/hydraExtensions/{interfaceImp.h => mayaHydraLibInterfaceImp.h} (78%) create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/infoClientTest.h create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testFlowViewportAPIViewportInformation.py create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationMultipleViewports.cpp create mode 100644 test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationRendererSwitching.cpp diff --git a/lib/flowViewport/API/CMakeLists.txt b/lib/flowViewport/API/CMakeLists.txt index 2df5b785c5..49a2fbc270 100644 --- a/lib/flowViewport/API/CMakeLists.txt +++ b/lib/flowViewport/API/CMakeLists.txt @@ -2,6 +2,8 @@ set(HEADERS fvpSelectionClient.h fvpFlowSelectionInterface.h fvpVersionInterface.h + fvpInformationInterface.h + fvpInformationClient.h ) # ----------------------------------------------------------------------------- @@ -27,3 +29,4 @@ install(FILES ${HEADERS} # ----------------------------------------------------------------------------- add_subdirectory(interfacesImp) add_subdirectory(samples) +add_subdirectory(perViewportSceneIndicesData) diff --git a/lib/flowViewport/API/fvpInformationClient.h b/lib/flowViewport/API/fvpInformationClient.h new file mode 100644 index 0000000000..223e110808 --- /dev/null +++ b/lib/flowViewport/API/fvpInformationClient.h @@ -0,0 +1,63 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + + +/// Is the definition of a callbacks InformationClient for an Hydra viewport. + +#ifndef FLOW_VIEWPORT_API_INFORMATION_CLIENT_H +#define FLOW_VIEWPORT_API_INFORMATION_CLIENT_H + +#include "flowViewport/api.h" + +#include "fvpInformationInterface.h" + +namespace FVP_NS_DEF +{ + ///Subclass this to create a client and register it through the InformationInterface class + class InformationClient + { + public: + + /** + * @brief Callback function called when an Hydra viewport scene index is being created by our Hydra viewport plugin + * + * This is a callback function that gets called when an Hydra viewport scene index is being created by our Hydra viewport plugin. + * A typical case is when an Hydra viewport is created. + * + * @param[in] viewportInformation is an Hydra viewport information from the scene index being added by our Hydra viewport plugin. + */ + virtual void SceneIndexAdded(const InformationInterface::ViewportInformation& viewportInformation) = 0; + + /** + * @brief Callback function called when an Hydra viewport scene index is being removed by our Hydra viewport plugin + * + * This is a callback function that gets called when an Hydra viewport scene index is removed by our Hydra viewport plugin. + * A typical case is when an Hydra viewport is removed. + * + * @param[in] viewportInformation is an Hydra viewport information from the scene index being removed by our Hydra viewport plugin. + */ + virtual void SceneIndexRemoved(const InformationInterface::ViewportInformation& viewportInformation) = 0; + + /// Destructor + virtual ~InformationClient() = default; + }; + + /// Set of InformationClient + using SharedInformationClientPtrSet = std::set>; + +}//end of namespace + +#endif //FLOW_VIEWPORT_API_INFORMATION_CLIENT_H diff --git a/lib/flowViewport/API/fvpInformationInterface.h b/lib/flowViewport/API/fvpInformationInterface.h new file mode 100644 index 0000000000..21dc06b904 --- /dev/null +++ b/lib/flowViewport/API/fvpInformationInterface.h @@ -0,0 +1,98 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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 FLOW_VIEWPORT_API_INFORMATION_INTERFACE_H +#define FLOW_VIEWPORT_API_INFORMATION_INTERFACE_H + +//Local headers +#include "flowViewport/api.h" + +//Hydra headers +#include + +namespace FVP_NS_DEF +{ + class InformationClient;//Predeclaration + + /*!\class InformationInterface + \brief : interface for a customer to register a callbacks InformationClient to get Hydra viewports information. + * To get an instance of the InformationInterface class, please use : + * Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + */ + class InformationInterface + { + public: + + ///Interface accessor + static FVP_API InformationInterface& Get(); + + ///Struct used to store information about an Hydra viewport from the DCC + struct ViewportInformation + { + /// Constructor + ViewportInformation(const std::string& viewportId, const std::string& cameraName) + : _viewportId(viewportId), _cameraName(cameraName) {} + + ///_viewportId is an Hydra viewport string identifier which is unique for all hydra viewports during a session + const std::string _viewportId; + + ///_cameraName is the name of the camera/viewport when the viewport was created, it is not updated if the camera's name has changed. + const std::string _cameraName; + + ///_rendererName is the Hydra viewport renderer name (example : "GL" for Storm or "Arnold" for the Arnold render delegate) + std::string _rendererName; + + bool operator ==(const ViewportInformation& other)const{ + return _viewportId == other._viewportId && + _cameraName == other._cameraName && + _rendererName == other._rendererName; + } + + bool operator <(const ViewportInformation& other) const{ //to be used in std::set + auto a = {_viewportId, _cameraName, _rendererName}; + auto b = {other._viewportId, other._cameraName, other._rendererName}; + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); + } + }; + + ///Set of InformationInterface::ViewportInformation + typedef std::set ViewportInformationSet; + + /** + * @brief Register a set of callbacks through an InformationClient instance + * + * @param[in] client is the InformationClient. + */ + virtual void RegisterInformationClient(const std::shared_ptr& client) = 0; + + /** + * @brief Unregister an InformationClient instance + * + * @param[in] client is the InformationClient. + */ + virtual void UnregisterInformationClient(const std::shared_ptr& client)= 0; + + /** + * @brief Get the Hydra viewports information. + * + * @param[out] outAllHydraViewportInformation is a set of ViewportInformation to have information about each Hydra viewport in use in the current DCC. + */ + virtual void GetViewportsInformation(ViewportInformationSet& outAllHydraViewportInformation)const = 0; + }; + +}//end of namespace + +#endif //FLOW_VIEWPORT_API_INFORMATION_INTERFACE_H diff --git a/lib/flowViewport/API/fvpSelectionClient.h b/lib/flowViewport/API/fvpSelectionClient.h index 6166578a4e..9f7b2b28da 100644 --- a/lib/flowViewport/API/fvpSelectionClient.h +++ b/lib/flowViewport/API/fvpSelectionClient.h @@ -20,7 +20,7 @@ #include "flowViewport/api.h" #include -#include +#include namespace FVP_NS_DEF { diff --git a/lib/flowViewport/API/interfacesImp/CMakeLists.txt b/lib/flowViewport/API/interfacesImp/CMakeLists.txt index 5bd63fedbc..5fbd5d89f4 100644 --- a/lib/flowViewport/API/interfacesImp/CMakeLists.txt +++ b/lib/flowViewport/API/interfacesImp/CMakeLists.txt @@ -5,11 +5,13 @@ target_sources(${TARGET_NAME} PRIVATE fvpSelectionInterfaceImp.cpp fvpVersionInterfaceImp.cpp + fvpInformationInterfaceImp.cpp ) set(HEADERS fvpSelectionInterfaceImp.h fvpVersionInterfaceImp.h + fvpInformationInterfaceImp.h ) # ----------------------------------------------------------------------------- diff --git a/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.cpp b/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.cpp new file mode 100644 index 0000000000..6424177818 --- /dev/null +++ b/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.cpp @@ -0,0 +1,100 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + +//Local headers +#include "fvpInformationInterfaceImp.h" +#include "flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h" + +#include + +namespace{ + std::mutex _viewportInformationClient_mutex; + + //Set of information clients + FVP_NS_DEF::SharedInformationClientPtrSet _viewportInformationClients; +} + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace FVP_NS_DEF { + + +InformationInterface& InformationInterface::Get() +{ + return InformationInterfaceImp::Get(); +} + +InformationInterfaceImp& InformationInterfaceImp::Get() +{ + static InformationInterfaceImp theInterface; + return theInterface; +} + +void InformationInterfaceImp::RegisterInformationClient(const std::shared_ptr& client) +{ + TF_AXIOM(client); + + std::lock_guard lock(_viewportInformationClient_mutex); + + auto foundResult = _viewportInformationClients.find(client); + if (foundResult == _viewportInformationClients.cend()){ + _viewportInformationClients.insert(client); + } +} + +void InformationInterfaceImp::UnregisterInformationClient(const std::shared_ptr& client) +{ + std::lock_guard lock(_viewportInformationClient_mutex); + + auto foundResult = _viewportInformationClients.find(client); + if (foundResult != _viewportInformationClients.end()){ + _viewportInformationClients.erase(foundResult); + } +} + +void InformationInterfaceImp::SceneIndexAdded(const InformationInterface::ViewportInformation& _viewportInfo) +{ + std::lock_guard lock(_viewportInformationClient_mutex); + for (auto viewportInfoClient : _viewportInformationClients){ + if (viewportInfoClient){ + viewportInfoClient->SceneIndexAdded(_viewportInfo); + } + } +} + +void InformationInterfaceImp::SceneIndexRemoved(const InformationInterface::ViewportInformation& _viewportInfo) +{ + std::lock_guard lock(_viewportInformationClient_mutex); + for (auto viewportInfoClient : _viewportInformationClients){ + if (viewportInfoClient){ + viewportInfoClient->SceneIndexRemoved(_viewportInfo); + } + } +} + +void InformationInterfaceImp::GetViewportsInformation(ViewportInformationSet& outHydraViewportInformationArray)const +{ + outHydraViewportInformationArray.clear(); + const ViewportInformationAndSceneIndicesPerViewportDataSet& allViewportInformationAndSceneIndicesPerViewportData = + ViewportInformationAndSceneIndicesPerViewportDataManager::Get().GetViewportInfoAndSceneIndicesPerViewportData(); + for (const ViewportInformationAndSceneIndicesPerViewportData& viewportInformationAndSceneIndicesPerViewportData : allViewportInformationAndSceneIndicesPerViewportData){ + const InformationInterface::ViewportInformation& viewportInfo = viewportInformationAndSceneIndicesPerViewportData.GetViewportInformation(); + outHydraViewportInformationArray.insert(viewportInfo); + } +} + +} //End of namespace FVP_NS_DEF { + diff --git a/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h b/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h new file mode 100644 index 0000000000..edc7e4e3a8 --- /dev/null +++ b/lib/flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h @@ -0,0 +1,50 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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 FLOW_VIEWPORT_API_INTERFACESIMP_INFORMATION_INTERFACE_IMP_H +#define FLOW_VIEWPORT_API_INTERFACESIMP_INFORMATION_INTERFACE_IMP_H + +//Local headers +#include +#include +#include + +namespace FVP_NS_DEF { + +///Is a singleton, use InformationInterfaceImp& InformationInterfaceImp::Get() to get an instance of that interface +class InformationInterfaceImp : public InformationInterface +{ +public: + virtual ~InformationInterfaceImp() = default; + + ///Interface accessor + static FVP_API InformationInterfaceImp& Get(); + + //From InformationInterface + void RegisterInformationClient(const std::shared_ptr& client)override; + void UnregisterInformationClient(const std::shared_ptr& client)override; + void GetViewportsInformation(ViewportInformationSet& outHydraviewportInformationSet) const override; + + void SceneIndexAdded(const InformationInterface::ViewportInformation& _viewportInfo); + void SceneIndexRemoved(const InformationInterface::ViewportInformation& viewportInfo); + +private: + InformationInterfaceImp() = default; +}; + +} //End of namespace FVP_NS_DEF + +#endif // FLOW_VIEWPORT_API_INTERFACESIMP_INFORMATION_INTERFACE_IMP_H \ No newline at end of file diff --git a/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.cpp b/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.cpp index 6e73ee50f2..aa2bd3969f 100644 --- a/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.cpp +++ b/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.cpp @@ -21,24 +21,23 @@ #include namespace{ - static std::mutex _viewportSelectClient_mutex; + std::mutex _viewportSelectClient_mutex; } PXR_NAMESPACE_USING_DIRECTIVE namespace FVP_NS_DEF { -static SelectionInterfaceImp theInterface; - SelectionClientSet _viewportSelectionClients; FlowSelectionInterface& FlowSelectionInterface::Get() { - return theInterface; + return SelectionInterfaceImp::Get(); } SelectionInterfaceImp& SelectionInterfaceImp::Get() { + static SelectionInterfaceImp theInterface; return theInterface; } diff --git a/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.h b/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.h index 2bba24c526..90ff7cbe8c 100644 --- a/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.h +++ b/lib/flowViewport/API/interfacesImp/fvpSelectionInterfaceImp.h @@ -28,7 +28,6 @@ namespace FVP_NS_DEF { class SelectionInterfaceImp : public FVP_NS_DEF::FlowSelectionInterface { public: - SelectionInterfaceImp() = default; virtual ~SelectionInterfaceImp() = default; ///Interface accessor @@ -40,6 +39,9 @@ class SelectionInterfaceImp : public FVP_NS_DEF::FlowSelectionInterface //To be called by maya-hydra void DummySelectionCallback(); + +private: + SelectionInterfaceImp() = default; }; } //End of namespace FVP_NS_DEF diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/CMakeLists.txt b/lib/flowViewport/API/perViewportSceneIndicesData/CMakeLists.txt new file mode 100644 index 0000000000..dac1c529e1 --- /dev/null +++ b/lib/flowViewport/API/perViewportSceneIndicesData/CMakeLists.txt @@ -0,0 +1,31 @@ +# ----------------------------------------------------------------------------- +# sources +# ----------------------------------------------------------------------------- +target_sources(${TARGET_NAME} + PRIVATE + fvpViewportInformationAndSceneIndicesPerViewportData.cpp + fvpViewportInformationAndSceneIndicesPerViewportDataManager.cpp +) + +set(HEADERS + fvpViewportInformationAndSceneIndicesPerViewportData.h + fvpViewportInformationAndSceneIndicesPerViewportDataManager.h +) + +# ----------------------------------------------------------------------------- +# promoted headers +# ----------------------------------------------------------------------------- +mayaUsd_promoteHeaderList( + HEADERS + ${HEADERS} + BASEDIR + ${TARGET_NAME}/API/perViewportSceneIndicesData +) + +# ----------------------------------------------------------------------------- +# install +# ----------------------------------------------------------------------------- +install(FILES ${HEADERS} + DESTINATION + ${CMAKE_INSTALL_PREFIX}/include/flowViewport/API/perViewportSceneIndicesData +) diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp new file mode 100644 index 0000000000..06ef8cb680 --- /dev/null +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.cpp @@ -0,0 +1,40 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + +//Local headers +#include "fvpViewportInformationAndSceneIndicesPerViewportData.h" +#include "flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h" +#include "flowViewport/sceneIndex/fvpRenderIndexProxy.h" + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace FVP_NS_DEF { + +ViewportInformationAndSceneIndicesPerViewportData::ViewportInformationAndSceneIndicesPerViewportData(const InformationInterface::ViewportInformation& viewportInformation) + : _viewportInformation(viewportInformation) +{ +} + +void ViewportInformationAndSceneIndicesPerViewportData::SetRenderIndexProxy(const Fvp::RenderIndexProxyPtr& renderIndexProxy) +{ + _renderIndexProxy = renderIndexProxy; + if (_renderIndexProxy){ + _viewportInformation._rendererName = _renderIndexProxy->GetRendererDisplayName(); + } +} + +} //End of namespace FVP_NS_DEF { + diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.h b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.h new file mode 100644 index 0000000000..06abbf7a77 --- /dev/null +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportData.h @@ -0,0 +1,67 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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 FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA +#define FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA + +//Local headers +#include "flowViewport/api.h" +#include "flowViewport/API/fvpInformationInterface.h" +#include "flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h" + +namespace FVP_NS_DEF { + +/** Stores information and misc. scene indices data per viewport +* So, if there are "n" Hydra viewports in the DCC, we will have "n" instances of this class. +*/ + +class ViewportInformationAndSceneIndicesPerViewportData +{ +public: + ViewportInformationAndSceneIndicesPerViewportData(const InformationInterface::ViewportInformation& viewportInformation); + ~ViewportInformationAndSceneIndicesPerViewportData() = default; + + const InformationInterface::ViewportInformation& GetViewportInformation()const { return _viewportInformation;} + const PXR_NS::HdSceneIndexBaseRefPtr& GetLastFilteringSceneIndexOfTheChain() const {return _lastFilteringSceneIndexOfTheChain;} + void SetRenderIndexProxy(const Fvp::RenderIndexProxyPtr& renderIndexProxy); + const Fvp::RenderIndexProxyPtr GetRenderIndexProxy() const {return _renderIndexProxy;} + void SetInputSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex) {_inputSceneIndex = inputSceneIndex;} + const PXR_NS::HdSceneIndexBaseRefPtr& GetInputSceneIndex() const {return _inputSceneIndex;} + + //Needed by std::set + bool operator < (const ViewportInformationAndSceneIndicesPerViewportData& other)const{ + return _viewportInformation < other._viewportInformation; //Is for std::set. + } + +private: + ///Hydra viewport information + InformationInterface::ViewportInformation _viewportInformation; + + ///Is the scene index we should use as an input for the custom filtering scene indices chain + PXR_NS::HdSceneIndexBaseRefPtr _inputSceneIndex {nullptr}; + + /// The last scene index of the custom filtering scene indices chain for this viewport + PXR_NS::HdSceneIndexBaseRefPtr _lastFilteringSceneIndexOfTheChain {nullptr}; + + ///Is a render index proxy per viewport to avoid accessing directly the render index + Fvp::RenderIndexProxyPtr _renderIndexProxy {nullptr}; +}; + +using ViewportInformationAndSceneIndicesPerViewportDataSet = std::set; + +} //End of namespace FVP_NS_DEF + +#endif // FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA \ No newline at end of file diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.cpp b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.cpp new file mode 100644 index 0000000000..0f8d800749 --- /dev/null +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.cpp @@ -0,0 +1,110 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + +//Local headers +#include "fvpViewportInformationAndSceneIndicesPerViewportDataManager.h" +#include "flowViewport/API/interfacesImp/fvpInformationInterfaceImp.h" +#include "flowViewport/sceneIndex/fvpRenderIndexProxy.h" + +//Hydra headers +#include + +//STL Headers +#include + +namespace +{ + std::mutex _viewportInformationAndSceneIndicesPerViewportDataSet_mutex; +} + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace FVP_NS_DEF { + +ViewportInformationAndSceneIndicesPerViewportDataManager& ViewportInformationAndSceneIndicesPerViewportDataManager::Get() +{ + static ViewportInformationAndSceneIndicesPerViewportDataManager theViewportInformationAndSceneIndicesPerViewportDataManager; + return theViewportInformationAndSceneIndicesPerViewportDataManager; +} + +//A new Hydra viewport was created +void ViewportInformationAndSceneIndicesPerViewportDataManager::AddViewportInformation(const InformationInterface::ViewportInformation& viewportInfo) +{ + //Add it in our array if it is not already inside + { + std::lock_guard lock(_viewportInformationAndSceneIndicesPerViewportDataSet_mutex); + + if ((_viewportsInformationAndSceneIndicesPerViewportData.count(viewportInfo) == 1)){ + return;//It is already inside our array + } + + _viewportsInformationAndSceneIndicesPerViewportData.insert(ViewportInformationAndSceneIndicesPerViewportData(viewportInfo)); + } + + //Let the registered clients know a new viewport has been added + InformationInterfaceImp::Get().SceneIndexAdded(viewportInfo); +} + +void ViewportInformationAndSceneIndicesPerViewportDataManager::RemoveViewportInformation(const std::string& modelPanel) +{ + //Block for the lifetime of the lock + { + std::lock_guard lock(_viewportInformationAndSceneIndicesPerViewportDataSet_mutex); + + auto findResult = std::find_if(_viewportsInformationAndSceneIndicesPerViewportData.begin(), _viewportsInformationAndSceneIndicesPerViewportData.end(), + [&modelPanel](const ViewportInformationAndSceneIndicesPerViewportData& other) { return other.GetViewportInformation()._viewportId == modelPanel;}); + if (findResult != _viewportsInformationAndSceneIndicesPerViewportData.end()){ + + InformationInterfaceImp::Get().SceneIndexRemoved(findResult->GetViewportInformation()); + + const Fvp::RenderIndexProxyPtr renderIndexProxy = findResult->GetRenderIndexProxy();//Get the pointer on the renderIndexProxy + + if(renderIndexProxy){ + //Destroy the custom filtering scene indices chain + //Following code is equivalent to calling FilteringSceneIndicesChainManager::GetManager().DestroyFilteringSceneIndicesChain(*renderIndexProxy); + //But we cannot do so because of the lock above. + auto renderIndex = renderIndexProxy->GetRenderIndex(); + if (renderIndex && findResult->GetLastFilteringSceneIndexOfTheChain()){ + renderIndex->RemoveSceneIndex(findResult->GetLastFilteringSceneIndexOfTheChain());//Remove the whole chain from the render index + } + } + + _viewportsInformationAndSceneIndicesPerViewportData.erase(findResult); + } + } +} + +void ViewportInformationAndSceneIndicesPerViewportDataManager::UpdateRenderIndexProxy(const std::string& modelPanel, const Fvp::RenderIndexProxyPtr& renderIndexProxy) +{ + if (! renderIndexProxy){ + return; + } + + auto findResult = std::find_if(_viewportsInformationAndSceneIndicesPerViewportData.begin(), _viewportsInformationAndSceneIndicesPerViewportData.end(), + [&modelPanel](const ViewportInformationAndSceneIndicesPerViewportData& other) { return other.GetViewportInformation()._viewportId == modelPanel;}); + if (findResult != _viewportsInformationAndSceneIndicesPerViewportData.end()){ + if(findResult->GetRenderIndexProxy()){ + return; //Already updated + } + + auto& item = *findResult; + ViewportInformationAndSceneIndicesPerViewportData& nonConstItem = const_cast(item); + nonConstItem.SetRenderIndexProxy(renderIndexProxy); + } +} + +} //End of namespace FVP_NS_DEF { + diff --git a/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h new file mode 100644 index 0000000000..3f202a8849 --- /dev/null +++ b/lib/flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h @@ -0,0 +1,61 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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 FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA_MANAGER +#define FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA_MANAGER + +//Local headers +#include "fvpViewportInformationAndSceneIndicesPerViewportData.h" +#include "flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h" + +//Hydra headers +#include + +namespace FVP_NS_DEF { + +/** Is a singleton to manage the ViewportInformationAndSceneIndicesPerViewportData which stores information and misc. scene indices data per viewport +* So, if there are "n" Hydra viewports in the DCC, we will have "n" instances of ViewportInformationAndSceneIndicesPerViewportData. +* +* To get an instance of this class, please use +* ViewportInformationAndSceneIndicesPerViewportDataManager& manager = ViewportInformationAndSceneIndicesPerViewportDataManager:Get(); +*/ +class FVP_API ViewportInformationAndSceneIndicesPerViewportDataManager +{ +public: + + /// Manager accessor + static ViewportInformationAndSceneIndicesPerViewportDataManager& Get(); + + ///A new Hydra viewport was created + void AddViewportInformation(const InformationInterface::ViewportInformation& _viewportInfo); + + ///An Hydra viewport was deleted + void RemoveViewportInformation(const std::string& modelPanel); + + const ViewportInformationAndSceneIndicesPerViewportDataSet& GetViewportInfoAndSceneIndicesPerViewportData() const {return _viewportsInformationAndSceneIndicesPerViewportData;} + + void UpdateRenderIndexProxy(const std::string& modelPanel, const Fvp::RenderIndexProxyPtr& renderIndexProxy); + +private: + ///Hydra viewport information + ViewportInformationAndSceneIndicesPerViewportDataSet _viewportsInformationAndSceneIndicesPerViewportData; + + ViewportInformationAndSceneIndicesPerViewportDataManager() = default; +}; + +} //End of namespace FVP_NS_DEF + +#endif // FLOW_VIEWPORT_API_PERVIEWPORTSCENEINDICESDATA_VIEWPORT_INFORMATION_AND_SCENE_INDICES_DATA_PER_VIEWPORT_DATA_MANAGER \ No newline at end of file diff --git a/lib/flowViewport/API/samples/CMakeLists.txt b/lib/flowViewport/API/samples/CMakeLists.txt index 3b50d4ee66..d19e5dd25f 100644 --- a/lib/flowViewport/API/samples/CMakeLists.txt +++ b/lib/flowViewport/API/samples/CMakeLists.txt @@ -4,10 +4,12 @@ target_sources(${TARGET_NAME} PRIVATE fvpSelectionClientExample.cpp + fvpInformationClientExample.cpp ) set(HEADERS fvpSelectionClientExample.h + fvpInformationClientExample.h ) # ----------------------------------------------------------------------------- diff --git a/lib/flowViewport/API/samples/fvpInformationClientExample.cpp b/lib/flowViewport/API/samples/fvpInformationClientExample.cpp new file mode 100644 index 0000000000..4b7813a281 --- /dev/null +++ b/lib/flowViewport/API/samples/fvpInformationClientExample.cpp @@ -0,0 +1,39 @@ +// +// 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. +// + +//Local headers +#include "fvpInformationClientExample.h" + +PXR_NAMESPACE_USING_DIRECTIVE + +namespace FVP_NS_DEF { + +InformationClientExample::~InformationClientExample() +{ +} + +//Callback to be able to act when an hydra viewport scene index was added, typical use case is an hydra viewport was created. +void InformationClientExample::SceneIndexAdded(const InformationInterface::ViewportInformation& viewportInformation) +{ + +} + +//Callback to be able to act when an hydra viewport scene index was removed, typical use case is an hydra viewport was removed. +void InformationClientExample::SceneIndexRemoved(const InformationInterface::ViewportInformation& viewportInformation) +{ +} + +} //End of namespace FVP_NS_DEF \ No newline at end of file diff --git a/lib/flowViewport/API/samples/fvpInformationClientExample.h b/lib/flowViewport/API/samples/fvpInformationClientExample.h new file mode 100644 index 0000000000..744f41aab3 --- /dev/null +++ b/lib/flowViewport/API/samples/fvpInformationClientExample.h @@ -0,0 +1,73 @@ +// +// 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 FLOW_VIEWPORT_EXAMPLES_INFORMATION_CLIENT_EXAMPLE_H +#define FLOW_VIEWPORT_EXAMPLES_INFORMATION_CLIENT_EXAMPLE_H + +//Local headers +#include "flowViewport/api.h" +#include "flowViewport/API/fvpInformationClient.h" + +namespace FVP_NS_DEF { + +class FilteringSceneIndexClientExample;//Predeclaration + +///Implementation of a FlowViewport::InformationClient which is the way to communicate with our Hydra plugin related to viewports information +class FVP_API InformationClientExample : public InformationClient +{ +public: + InformationClientExample() = default; + ~InformationClientExample() override; + + ///Set the hydra interface + void SetHydraInterface(InformationInterface* hydraInterface) {_hydraInterface = hydraInterface;} + + /// set the filtering scene index client example + void SetFilteringSceneIndexClientExample(FilteringSceneIndexClientExample& hydraViewportFilteringSceneIndexClientExample) + {_hydraViewportFilteringSceneIndexClientExample = &hydraViewportFilteringSceneIndexClientExample;} + + //From FlowViewport::InformationClient + + /** + * @brief Callback function called when an Hydra viewport scene index is being created by our Hydra viewport plugin + * + * This is a callback function that gets called when an Hydra viewport scene index is being created by our Hydra viewport plugin. + * A typical case is when an Hydra viewport is created. + * + * @param[in] viewportInformation is a viewport information from the scene index being added by our Hydra viewport plugin. + */ + void SceneIndexAdded(const InformationInterface::ViewportInformation& viewportInformation)override; + + /** + * @brief Callback function called when an Hydra viewport scene index is being removed by our Hydra viewport plugin + * + * This is a callback function that gets called when an Hydra viewport scene index is removed by our Hydra viewport plugin. + * A typical case is when an Hydra viewport is removed. + * + * @param[in] viewportInformation is a viewport information from the scene index being removed by our Hydra viewport plugin. + */ + void SceneIndexRemoved(const InformationInterface::ViewportInformation& viewportInformation)override; + +protected: + ///Store the Hydra interface + InformationInterface* _hydraInterface = nullptr; + + ///Store an FilteringSceneIndexClientExample since it needs to be aware of the viewports being removed + FilteringSceneIndexClientExample* _hydraViewportFilteringSceneIndexClientExample = nullptr; +}; + +}//end of namespace FVP_NS_DEF + +#endif //FLOW_VIEWPORT_EXAMPLES_INFORMATION_CLIENT_EXAMPLE_H diff --git a/lib/flowViewport/sceneIndex/CMakeLists.txt b/lib/flowViewport/sceneIndex/CMakeLists.txt index 019e55d697..ed1553fc99 100644 --- a/lib/flowViewport/sceneIndex/CMakeLists.txt +++ b/lib/flowViewport/sceneIndex/CMakeLists.txt @@ -16,6 +16,7 @@ set(HEADERS fvpPathInterface.h fvpPathInterfaceSceneIndex.h fvpRenderIndexProxy.h + fvpRenderIndexProxyFwd.h fvpSelectionSceneIndex.h fvpWireframeSelectionHighlightSceneIndex.h ) diff --git a/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.cpp b/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.cpp index 8f27cbe642..2fa80d2258 100644 --- a/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.cpp +++ b/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.cpp @@ -36,10 +36,14 @@ // limitations under the License. // +//Local headers #include "flowViewport/sceneIndex/fvpRenderIndexProxy.h" #include "flowViewport/sceneIndex/fvpMergingSceneIndex.h" +//Hydra headers #include +#include +#include PXR_NAMESPACE_USING_DIRECTIVE @@ -92,6 +96,10 @@ void RenderIndexProxy::RemoveSceneIndex( const HdSceneIndexBaseRefPtr &inputScene ) { + if (nullptr == inputScene || nullptr == _mergingSceneIndex){ + return; + } + // Copy-pasted and adapted from USD 0.23.08 // HdRenderIndex::RemoveSceneIndex() code, to preserve prefixing scene // index removal capability. PPT, 1-Sep-2023. @@ -121,9 +129,29 @@ void RenderIndexProxy::RemoveSceneIndex( } } -PXR_NS::HdSceneIndexBaseRefPtr RenderIndexProxy::GetMergingSceneIndex() const +HdSceneIndexBaseRefPtr RenderIndexProxy::GetMergingSceneIndex() const { return _mergingSceneIndex; } +HdRenderIndex* RenderIndexProxy::GetRenderIndex() const +{ + return _renderIndex; +} + +std::string RenderIndexProxy::GetRendererDisplayName() const +{ + static std::string empty; + + if (! _renderIndex){ + return empty; + } + auto rd = _renderIndex->GetRenderDelegate(); + if (! rd){ + return empty; + } + + return rd->GetRendererDisplayName(); } + +}//end of namespace FVP_NS_DEF \ No newline at end of file diff --git a/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.h b/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.h index 5865e439b8..351d3fb190 100644 --- a/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.h +++ b/lib/flowViewport/sceneIndex/fvpRenderIndexProxy.h @@ -79,18 +79,27 @@ class RenderIndexProxy FVP_API void RemoveSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr &inputScene); - // Return the additional Flow Viewport merging scene index onto which input - // scenes are added. Returned as a base scene index to preserve - // encapsulation. + /** Return the additional Flow Viewport merging scene index onto which input + * scenes are added. Returned as a base scene index to preserve + * encapsulation. + */ FVP_API PXR_NS::HdSceneIndexBaseRefPtr GetMergingSceneIndex() const; + ///Get the render index + FVP_API + PXR_NS::HdRenderIndex* GetRenderIndex() const; + + ///Get the render delegate display name + FVP_API + std::string GetRendererDisplayName() const; + private: PXR_NS::HdRenderIndex* const _renderIndex{nullptr}; PXR_NS::HdMergingSceneIndexRefPtr _mergingSceneIndex; }; -} +}//End of namespace FVP_NS_DEF -#endif +#endif //FVP_RENDER_INDEX_PROXY_H diff --git a/lib/flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h b/lib/flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h new file mode 100644 index 0000000000..14b84f8e57 --- /dev/null +++ b/lib/flowViewport/sceneIndex/fvpRenderIndexProxyFwd.h @@ -0,0 +1,28 @@ +// 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 FVP_RENDER_INDEX_PROXY_FWD_H +#define FVP_RENDER_INDEX_PROXY_FWD_H + +#include "flowViewport/api.h" + + +namespace FVP_NS_DEF { + +class RenderIndexProxy; +using RenderIndexProxyPtr = std::shared_ptr; + +}//End of namespace FVP_NS_DEF + +#endif //FVP_RENDER_INDEX_PROXY_FWD_H diff --git a/lib/mayaHydra/hydraExtensions/CMakeLists.txt b/lib/mayaHydra/hydraExtensions/CMakeLists.txt index 4b23d883ca..a244dcacbd 100644 --- a/lib/mayaHydra/hydraExtensions/CMakeLists.txt +++ b/lib/mayaHydra/hydraExtensions/CMakeLists.txt @@ -9,7 +9,7 @@ target_sources(${TARGET_NAME} PRIVATE debugCodes.cpp hydraUtils.cpp - interfaceImp.cpp + mayaHydraLibInterfaceImp.cpp mayaUtils.cpp mhBuildInfo.cpp mixedUtils.cpp @@ -20,8 +20,8 @@ set(HEADERS api.h debugCodes.h hydraUtils.h - interface.h - interfaceImp.h + mayaHydraLibInterface.h + mayaHydraLibInterfaceImp.h mayaUtils.h mixedUtils.h mayaHydraSceneProducer.h diff --git a/lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp b/lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp index 8972cda352..2d3e3aae4d 100644 --- a/lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp +++ b/lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp @@ -175,7 +175,7 @@ VtValue MayaHydraCameraAdapter::GetCameraParamValue(const TfToken& paramName) }; auto hadError = [&](MStatus& status) -> bool { - if (ARCH_LIKELY(status)) + if (status) return false; TF_WARN( "Error in MayaHydraCameraAdapter::GetCameraParamValue(%s): %s", diff --git a/lib/mayaHydra/hydraExtensions/adapters/materialAdapter.cpp b/lib/mayaHydra/hydraExtensions/adapters/materialAdapter.cpp index f603dd80b2..89880431c2 100644 --- a/lib/mayaHydra/hydraExtensions/adapters/materialAdapter.cpp +++ b/lib/mayaHydra/hydraExtensions/adapters/materialAdapter.cpp @@ -157,7 +157,7 @@ class MayaHydraShadingEngineAdapter : public MayaHydraMaterialAdapter MStatus status; auto obj = GetNode(); auto id = MNodeMessage::addNodeDirtyCallback(obj, _DirtyMaterialParams, this, &status); - if (ARCH_LIKELY(status)) { + if (status) { AddCallback(id); } _CreateSurfaceMaterialCallback(); diff --git a/lib/mayaHydra/hydraExtensions/adapters/shapeAdapter.cpp b/lib/mayaHydra/hydraExtensions/adapters/shapeAdapter.cpp index 0c297c8f45..90c09fa0f8 100644 --- a/lib/mayaHydra/hydraExtensions/adapters/shapeAdapter.cpp +++ b/lib/mayaHydra/hydraExtensions/adapters/shapeAdapter.cpp @@ -48,7 +48,7 @@ void MayaHydraShapeAdapter::_CalculateExtent() { MStatus status; MFnDagNode dagNode(GetDagPath(), &status); - if (ARCH_LIKELY(status)) { + if (status) { const auto bb = dagNode.boundingBox(); const auto mn = bb.min(); const auto mx = bb.max(); diff --git a/lib/mayaHydra/hydraExtensions/delegates/delegate.h b/lib/mayaHydra/hydraExtensions/delegates/delegate.h index 61b5bf66c5..9e1aa169e6 100644 --- a/lib/mayaHydra/hydraExtensions/delegates/delegate.h +++ b/lib/mayaHydra/hydraExtensions/delegates/delegate.h @@ -80,6 +80,14 @@ class MayaHydraDelegate SdfPath delegateID; bool isHdSt; MayaHydraSceneProducer* producer; + ///name of the camera/viewport. + std::string cameraName; + ///viewport width. + int viewportWidth; + ///viewport height. + int viewportHeight; + /// Is the Hydra renderer name for this viewport such as "GL" for Storm or "Arnold" for the Arnold render delegate. + std::string rendererName; }; MAYAHYDRALIB_API diff --git a/lib/mayaHydra/hydraExtensions/hydraUtils.cpp b/lib/mayaHydra/hydraExtensions/hydraUtils.cpp index 0a3b0b0f4b..62b1986c99 100644 --- a/lib/mayaHydra/hydraExtensions/hydraUtils.cpp +++ b/lib/mayaHydra/hydraExtensions/hydraUtils.cpp @@ -162,9 +162,9 @@ std::string StripNamespaces(const std::string& nodeName, const int nsDepth) std::stringstream ss; const std::vector nodeNameParts - = PXR_NS::TfStringSplit(nodeName, MayaDagDelimiter); + = TfStringSplit(nodeName, MayaDagDelimiter); - const bool isAbsolute = PXR_NS::TfStringStartsWith(nodeName, MayaDagDelimiter); + const bool isAbsolute = TfStringStartsWith(nodeName, MayaDagDelimiter); for (size_t i = 0u; i < nodeNameParts.size(); ++i) { if (i == 0u && isAbsolute) { @@ -179,7 +179,7 @@ std::string StripNamespaces(const std::string& nodeName, const int nsDepth) } const std::vector nsNameParts - = PXR_NS::TfStringSplit(nodeNameParts[i], MayaNamespaceDelimiter); + = TfStringSplit(nodeNameParts[i], MayaNamespaceDelimiter); const size_t nodeNameIndex = nsNameParts.size() - 1u; @@ -195,7 +195,7 @@ std::string StripNamespaces(const std::string& nodeName, const int nsDepth) startIter += std::min(static_cast(nsDepth), nodeNameIndex); } - ss << PXR_NS::TfStringJoin(startIter, nsNameParts.end(), MayaNamespaceDelimiter); + ss << TfStringJoin(startIter, nsNameParts.end(), MayaNamespaceDelimiter); } return ss.str(); @@ -219,7 +219,7 @@ void SanitizeNameForSdfPath(std::string& inoutPathString, bool doStripNamespaces inoutPathString.begin(), inoutPathString.end(), MayaDagDelimiter[0], - PXR_NS::SdfPathTokens->childDelimiter.GetString()[0]); + SdfPathTokens->childDelimiter.GetString()[0]); std::replace(inoutPathString.begin(), inoutPathString.end(), MayaNamespaceDelimiter[0], '_'); std::replace(inoutPathString.begin(), inoutPathString.end(), ',', '_'); std::replace(inoutPathString.begin(), inoutPathString.end(), ';', '_'); diff --git a/lib/mayaHydra/hydraExtensions/interface.h b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterface.h similarity index 81% rename from lib/mayaHydra/hydraExtensions/interface.h rename to lib/mayaHydra/hydraExtensions/mayaHydraLibInterface.h index 2aaa7e4907..2d5c0bf0a2 100644 --- a/lib/mayaHydra/hydraExtensions/interface.h +++ b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterface.h @@ -17,15 +17,16 @@ #ifndef MAYAHYDRALIB_INTERFACE_H #define MAYAHYDRALIB_INTERFACE_H -#include +//Local headers +#include "mayaHydraLib/api.h" +//Hydra headers #include -#include PXR_NAMESPACE_OPEN_SCOPE -using SceneIndicesVector = std::vector; +using SceneIndicesVector = std::vector;//Be careful, these are not not Ref counted. Elements could become dangling /// In order to access this interface, call the function GetMayaHydraLibInterface() class MayaHydraLibInterface @@ -36,14 +37,14 @@ class MayaHydraLibInterface * * @param[in] sceneIndex is a pointer to the SceneIndex to be registered. */ - virtual void RegisterTerminalSceneIndex(HdSceneIndexBasePtr sceneIndex) = 0; + virtual void RegisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) = 0; /** * @brief Unregister a terminal scene index from the Hydra plugin. * * @param[in] sceneIndex is a pointer to the SceneIndex to be unregistered. */ - virtual void UnregisterTerminalSceneIndex(HdSceneIndexBasePtr sceneIndex) = 0; + virtual void UnregisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) = 0; /** * @brief Clear the list of registered terminal scene indices diff --git a/lib/mayaHydra/hydraExtensions/interfaceImp.cpp b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.cpp similarity index 76% rename from lib/mayaHydra/hydraExtensions/interfaceImp.cpp rename to lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.cpp index ccfb841170..3123637b3f 100644 --- a/lib/mayaHydra/hydraExtensions/interfaceImp.cpp +++ b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.cpp @@ -1,4 +1,5 @@ -// Copyright 2023 Autodesk +// +// Copyright 2023 Autodesk, Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +14,8 @@ // limitations under the License. // -#include "interfaceImp.h" +//Local headers +#include "mayaHydraLibInterfaceImp.h" PXR_NAMESPACE_OPEN_SCOPE @@ -23,7 +25,12 @@ MayaHydraLibInterface& GetMayaHydraLibInterface() return libInterface; } -void MayaHydraLibInterfaceImp::RegisterTerminalSceneIndex(HdSceneIndexBasePtr sceneIndex) +MayaHydraLibInterfaceImp::~MayaHydraLibInterfaceImp() +{ + ClearTerminalSceneIndices(); +} + +void MayaHydraLibInterfaceImp::RegisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) { auto foundSceneIndex = std::find(_sceneIndices.begin(), _sceneIndices.end(), sceneIndex); if (foundSceneIndex == _sceneIndices.end()) { @@ -31,7 +38,7 @@ void MayaHydraLibInterfaceImp::RegisterTerminalSceneIndex(HdSceneIndexBasePtr sc } } -void MayaHydraLibInterfaceImp::UnregisterTerminalSceneIndex(HdSceneIndexBasePtr sceneIndex) +void MayaHydraLibInterfaceImp::UnregisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) { auto foundSceneIndex = std::find(_sceneIndices.begin(), _sceneIndices.end(), sceneIndex); if (foundSceneIndex != _sceneIndices.end()) { diff --git a/lib/mayaHydra/hydraExtensions/interfaceImp.h b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.h similarity index 78% rename from lib/mayaHydra/hydraExtensions/interfaceImp.h rename to lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.h index bdcef76e5b..7b10c0bf85 100644 --- a/lib/mayaHydra/hydraExtensions/interfaceImp.h +++ b/lib/mayaHydra/hydraExtensions/mayaHydraLibInterfaceImp.h @@ -17,26 +17,26 @@ #ifndef MAYAHYDRALIB_INTERFACE_IMP_H #define MAYAHYDRALIB_INTERFACE_IMP_H +//Local headers #include -#include +#include +//Hydra headers #include -#include - PXR_NAMESPACE_OPEN_SCOPE class MayaHydraLibInterfaceImp : public MayaHydraLibInterface { public: MayaHydraLibInterfaceImp() = default; - virtual ~MayaHydraLibInterfaceImp() = default; + virtual ~MayaHydraLibInterfaceImp(); - void RegisterTerminalSceneIndex(HdSceneIndexBasePtr) override; - void UnregisterTerminalSceneIndex(HdSceneIndexBasePtr) override; + void RegisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr&) override; + void UnregisterTerminalSceneIndex(const HdSceneIndexBaseRefPtr&) override; void ClearTerminalSceneIndices() override; const SceneIndicesVector& GetTerminalSceneIndices() const override; - + private: SceneIndicesVector _sceneIndices; }; diff --git a/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.cpp b/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.cpp index bcbcb0ea06..e20bbec28a 100644 --- a/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.cpp +++ b/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.cpp @@ -20,8 +20,11 @@ #include #include #include +#include #include +#include +#include #include @@ -36,7 +39,7 @@ bool enableMayaNativeSceneIndex() { } MayaHydraSceneProducer::MayaHydraSceneProducer( - Fvp::RenderIndexProxy& renderIndexProxy, + const std::shared_ptr& renderIndexProxy, const SdfPath& id, MayaHydraDelegate::InitData& initData, bool lightEnabled @@ -94,7 +97,9 @@ MayaHydraSceneProducer::~MayaHydraSceneProducer() { if (enableMayaNativeSceneIndex()) { - _sceneIndex->GetRenderIndex().RemoveSceneIndex(_sceneIndex); + _renderIndexProxy->RemoveSceneIndex(_sceneIndex); + _sceneIndex->RemoveCallbacksAndDeleteAdapters();//This should be called before calling _sceneIndex.Reset(); which will call the destructor if the ref count reaches 0 + _sceneIndex.Reset(); } _delegates.clear(); } @@ -116,8 +121,8 @@ void MayaHydraSceneProducer::Populate() if (enableMayaNativeSceneIndex()) { _sceneIndex->Populate(); - // Call InsertSceneIndex before prims are added to scene index, would it be better to call later? - _renderIndexProxy.InsertSceneIndex(_sceneIndex, SdfPath::AbsoluteRootPath()); + //Add the scene index as an input scene index of the merging scene index + _renderIndexProxy->InsertSceneIndex(_sceneIndex, SdfPath::AbsoluteRootPath()); } else { diff --git a/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.h b/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.h index 1eacf77273..6ae7776f9d 100644 --- a/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.h +++ b/lib/mayaHydra/hydraExtensions/mayaHydraSceneProducer.h @@ -60,7 +60,7 @@ class MAYAHYDRALIB_API MayaHydraSceneProducer { public: MayaHydraSceneProducer( - Fvp::RenderIndexProxy& renderIndexProxy, + const std::shared_ptr& renderIndexProxy, const SdfPath& id, MayaHydraDelegate::InitData& initData, bool lightEnabled); @@ -131,6 +131,7 @@ class MAYAHYDRALIB_API MayaHydraSceneProducer SdfPath GetPrimPath(const MDagPath& dg, bool isSprim); HdRenderIndex& GetRenderIndex(); + std::shared_ptr GetRenderIndexProxy(){ return _renderIndexProxy;} SdfPath GetLightedPrimsRootPath() const; @@ -197,7 +198,7 @@ class MAYAHYDRALIB_API MayaHydraSceneProducer // SceneIndex MayaHydraSceneIndexRefPtr _sceneIndex; - Fvp::RenderIndexProxy& _renderIndexProxy; + const std::shared_ptr _renderIndexProxy; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp index 75dcc9d101..b7ec9ea029 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -393,10 +394,19 @@ MayaHydraSceneIndex::MayaHydraSceneIndex( } MayaHydraSceneIndex::~MayaHydraSceneIndex() +{ + //If you get a crash in a callback with a nullptr for _sceneIndex, + // it may be due to the fact that the _sceneIndex pointer has been nulled as its ref count reached 0 but the destructor is still being called. + //You should call RemoveCallbacksAndDeleteAdapters(); before the destructor is called. +} + +void MayaHydraSceneIndex::RemoveCallbacksAndDeleteAdapters() { for (auto callback : _callbacks) { MMessage::removeCallback(callback); } + _callbacks.clear(); + _MapAdapter( [](MayaHydraAdapter* a) { a->RemoveCallbacks(); }, _renderItemsAdapters, @@ -404,7 +414,12 @@ MayaHydraSceneIndex::~MayaHydraSceneIndex() _lightAdapters, _materialAdapters); - SetDefaultLightEnabled(false); + _renderItemsAdapters.clear(); + _shapeAdapters.clear(); + _lightAdapters.clear(); + _materialAdapters.clear(); + _cameraAdapters.clear(); + _renderItemsAdaptersFast.clear(); } void MayaHydraSceneIndex::HandleCompleteViewportScene(const MDataServerOperation::MViewportScene& scene, MFrameContext::DisplayStyle ds) @@ -1481,4 +1496,12 @@ VtValue MayaHydraSceneIndex::GetShadingStyle(SdfPath const& id) return VtValue(); } +const std::shared_ptr MayaHydraSceneIndex::GetRenderIndexProxy() +{ + if (! _producer){ + TF_CODING_ERROR("The MayaHydraSceneProducer pointer should not be a nullptr !"); + } + return _producer->GetRenderIndexProxy(); +} + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.h b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.h index 031a20ee61..088cb7c7e6 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.h @@ -50,6 +50,10 @@ #include +namespace FVP_NS_DEF { +class RenderIndexProxy; +} + PXR_NAMESPACE_OPEN_SCOPE class MayaHydraSceneIndex; @@ -75,6 +79,9 @@ class MAYAHYDRALIB_API MayaHydraSceneIndex : public HdRetainedSceneIndex, public ~MayaHydraSceneIndex(); + //Call this before the destructor is called. + void RemoveCallbacksAndDeleteAdapters(); + // ------------------------------------------------------------------------ // Maya Hydra scene producer implementations // Propogate scene changes from Maya to Hydra @@ -163,6 +170,8 @@ class MAYAHYDRALIB_API MayaHydraSceneIndex : public HdRetainedSceneIndex, public MayaHydraSceneProducer* GetProducer() { return _producer; }; + const std::shared_ptr GetRenderIndexProxy(); + SdfPath SceneIndexPath(const Ufe::Path& appPath) const override; private: diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp index a4f830ef8e..c80c28ab09 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.cpp @@ -184,7 +184,7 @@ namespace { constexpr char kDagNodeMessageName[] = { "dagNode" }; } // MayaHydraSceneIndexRegistration is used to register a scene index for a given dag node type. -MayaHydraSceneIndexRegistry::MayaHydraSceneIndexRegistry(Fvp::RenderIndexProxy& renderIndexProxy) +MayaHydraSceneIndexRegistry::MayaHydraSceneIndexRegistry(const std::shared_ptr& renderIndexProxy) : _renderIndexProxy(renderIndexProxy) { // Begin registering of custom scene indices for given node types @@ -257,7 +257,7 @@ bool MayaHydraSceneIndexRegistry::_RemoveSceneIndexForNode(const MObject& dagNod auto it = _registrationsByObjectHandle.find(dagNodeHandle); if (it != _registrationsByObjectHandle.end()) { MayaHydraSceneIndexRegistrationPtr registration(it->second); - _renderIndexProxy.RemoveSceneIndex(registration->rootSceneIndex); + _renderIndexProxy->RemoveSceneIndex(registration->rootSceneIndex); _registrationsByObjectHandle.erase(dagNodeHandle); _registrations.erase(registration->sceneIndexPathPrefix); return true; @@ -267,7 +267,7 @@ bool MayaHydraSceneIndexRegistry::_RemoveSceneIndexForNode(const MObject& dagNod #if PXR_VERSION < 2308 HdSceneIndexBaseRefPtr -MayaHydraSceneIndexRegistry::_AppendTerminalRenamingSceneIndex(HdSceneIndexBaseRefPtr sceneIndex) +MayaHydraSceneIndexRegistry::_AppendTerminalRenamingSceneIndex(const HdSceneIndexBaseRefPtr& sceneIndex) { // Get the list of renderer supported material network implementations. TfTokenVector renderingContexts = @@ -373,7 +373,7 @@ void MayaHydraSceneIndexRegistry::_AddSceneIndexForNode(MObject& dagNode) // prefix, the chosen prefix will be prepended to rprims tied to that scene index // automatically. constexpr bool needsPrefixing = false; - _renderIndexProxy.InsertSceneIndex( + _renderIndexProxy->InsertSceneIndex( registration->rootSceneIndex, registration->sceneIndexPathPrefix, needsPrefixing); static SdfPath maya126790Workaround("maya126790Workaround"); diff --git a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h index bfa7025688..5de7b4f835 100644 --- a/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h +++ b/lib/mayaHydra/hydraExtensions/sceneIndex/registration.h @@ -82,7 +82,7 @@ class MayaHydraSceneIndexRegistry static constexpr Ufe::Rtid kInvalidUfeRtid = 0; MAYAHYDRALIB_API - MayaHydraSceneIndexRegistry(Fvp::RenderIndexProxy& renderIndexProxy); + MayaHydraSceneIndexRegistry(const std::shared_ptr& renderIndexProxy); MAYAHYDRALIB_API ~MayaHydraSceneIndexRegistry(); @@ -100,7 +100,7 @@ class MayaHydraSceneIndexRegistry bool _RemoveSceneIndexForNode(const MObject& dagNode); static void _SceneIndexNodeAddedCallback(MObject& obj, void* clientData); static void _SceneIndexNodeRemovedCallback(MObject& obj, void* clientData); - Fvp::RenderIndexProxy& _renderIndexProxy; + const std::shared_ptr _renderIndexProxy; MCallbackIdArray _sceneIndexDagNodeMessageCallbacks; diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.cpp b/lib/mayaHydra/mayaPlugin/renderOverride.cpp index be1863da75..3d412b4eab 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.cpp +++ b/lib/mayaHydra/mayaPlugin/renderOverride.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -108,6 +109,7 @@ template inline void hash_combine(std::size_t& seed, const T& value #include #include #include +#include #include #include @@ -408,6 +410,14 @@ SdfPath MtohRenderOverride::RendererSceneDelegateId(TfToken rendererName, TfToke return SdfPath(); } +void MtohRenderOverride::_UpdateRenderIndexProxyIfRequired(const MHWRender::MDrawContext& drawContext) +{ + //Get model panel name + MString modelPanel; + drawContext.renderingDestination(modelPanel); + Fvp::ViewportInformationAndSceneIndicesPerViewportDataManager::Get().UpdateRenderIndexProxy(modelPanel.asChar(), _renderIndexProxy); +} + void MtohRenderOverride::_DetectMayaDefaultLighting(const MHWRender::MDrawContext& drawContext) { constexpr auto considerAllSceneLights = MHWRender::MDrawContext::kFilteredIgnoreLightLimit; @@ -565,13 +575,15 @@ MStatus MtohRenderOverride::Render( return MStatus::kFailure; } + _UpdateRenderIndexProxyIfRequired(drawContext); + _DetectMayaDefaultLighting(drawContext); if (_needsClear.exchange(false)) { ClearHydraResources(); } if (!_initializationAttempted) { - _InitHydraResources(); + _InitHydraResources(drawContext); if (!_initializationSucceeded) { return MStatus::kFailure; @@ -720,7 +732,7 @@ void MtohRenderOverride::_SetRenderPurposeTags(const MayaHydraParams& delegatePa _taskController->SetRenderTags(mhRenderTags); } -void MtohRenderOverride::_InitHydraResources() +void MtohRenderOverride::_InitHydraResources(const MHWRender::MDrawContext& drawContext) { TF_DEBUG(MAYAHYDRALIB_RENDEROVERRIDE_RESOURCES) .Msg("MtohRenderOverride::_InitHydraResources(%s)\n", _rendererDesc.rendererName.GetText()); @@ -761,7 +773,8 @@ void MtohRenderOverride::_InitHydraResources() _rendererPlugin, _taskController, SdfPath(), - _isUsingHdSt); + _isUsingHdSt + ); // Render index proxy sets up the Flow Viewport merging scene index, must // be created first, as it is required for: @@ -770,35 +783,16 @@ void MtohRenderOverride::_InitHydraResources() // - Maya scene producer, which needs the render index proxy to insert // itself. - _renderIndexProxy = std::make_unique(_renderIndex); + _renderIndexProxy = std::make_shared(_renderIndex); - _mayaHydraSceneProducer.reset(new MayaHydraSceneProducer(*_renderIndexProxy, _ID, delegateInitData, !_hasDefaultLighting)); + _mayaHydraSceneProducer.reset(new MayaHydraSceneProducer(_renderIndexProxy, _ID, delegateInitData, !_hasDefaultLighting)); VtValue fvpSelectionTrackerValue(_fvpSelectionTracker); _engine.SetTaskContextData(FvpTokens->fvpSelectionState, fvpSelectionTrackerValue); _mayaHydraSceneProducer->Populate(); - - _selection = std::make_shared(); - _selectionSceneIndex = Fvp::SelectionSceneIndex::New(_renderIndexProxy->GetMergingSceneIndex(), _selection); - _selectionSceneIndex->SetDisplayName("Flow Viewport Selection Scene Index"); - - if (!_sceneIndexRegistry) { - _sceneIndexRegistry.reset(new MayaHydraSceneIndexRegistry(*_renderIndexProxy)); - } - - auto wfSi = TfDynamic_cast(Fvp::WireframeSelectionHighlightSceneIndex::New(_selectionSceneIndex, _selection)); - wfSi->SetDisplayName("Flow Viewport Wireframe Selection Highlight Scene Index"); - - // At time of writing, wireframe selection highlighting of Maya native data - // is done by Maya at render item creation time, so avoid double wireframe - // selection highlighting. - wfSi->addExcludedSceneRoot(_ID); - - _renderIndex->InsertSceneIndex(wfSi, SdfPath::AbsoluteRootPath()); - - // Set the initial selection onto the selection scene index. - _selectionSceneIndex->ReplaceSelection(*Ufe::GlobalSelection::get()); + + _CreateSceneIndicesChainAfterMergingSceneIndex(); if (auto* renderDelegate = _GetRenderDelegate()) { // Pull in any options that may have changed due file-open. @@ -830,7 +824,6 @@ void MtohRenderOverride::ClearHydraResources() TF_DEBUG(MAYAHYDRALIB_RENDEROVERRIDE_RESOURCES) .Msg("MtohRenderOverride::ClearHydraResources(%s)\n", _rendererDesc.rendererName.GetText()); - _renderIndexProxy.reset(); _mayaHydraSceneProducer.reset(); _selectionSceneIndex.Reset(); _selection.reset(); @@ -858,16 +851,51 @@ void MtohRenderOverride::ClearHydraResources() _sceneIndexRegistry.reset(); + //Decrease ref count on the render index proxy which owns the merging scene index at the end of this function as some previous calls may likely use it to remove some scene indices + _renderIndexProxy.reset(); + _viewport = GfVec4d(0, 0, 0, 0); _initializationSucceeded = false; _initializationAttempted = false; } +void MtohRenderOverride::_CreateSceneIndicesChainAfterMergingSceneIndex() +{ + //This function is where happens the ordering of filtering scene indices that are after the merging scene index + TF_AXIOM(_renderIndexProxy); + + HdSceneIndexBaseRefPtr lastSceneIndexOfTheChain = _renderIndexProxy->GetMergingSceneIndex(); + + _selection = std::make_shared(); + _selectionSceneIndex = Fvp::SelectionSceneIndex::New(lastSceneIndexOfTheChain, _selection); + _selectionSceneIndex->SetDisplayName("Flow Viewport Selection Scene Index"); + lastSceneIndexOfTheChain = _selectionSceneIndex; + + if (!_sceneIndexRegistry) { + _sceneIndexRegistry.reset(new MayaHydraSceneIndexRegistry(_renderIndexProxy)); + } + + auto wfSi = TfDynamic_cast(Fvp::WireframeSelectionHighlightSceneIndex::New(_selectionSceneIndex, _selection)); + wfSi->SetDisplayName("Flow Viewport Wireframe Selection Highlight Scene Index"); + + // At time of writing, wireframe selection highlighting of Maya native data + // is done by Maya at render item creation time, so avoid double wireframe + // selection highlighting. + wfSi->addExcludedSceneRoot(_ID); + lastSceneIndexOfTheChain = wfSi; + + _renderIndex->InsertSceneIndex(lastSceneIndexOfTheChain, SdfPath::AbsoluteRootPath()); + + // Set the initial selection onto the selection scene index. + _selectionSceneIndex->ReplaceSelection(*Ufe::GlobalSelection::get()); +} + void MtohRenderOverride::_RemovePanel(MString panelName) { auto foundPanelCallbacks = _FindPanelCallbacks(panelName); if (foundPanelCallbacks != _renderPanelCallbacks.end()) { MMessage::removeCallbacks(foundPanelCallbacks->second); + Fvp::ViewportInformationAndSceneIndicesPerViewportDataManager::Get().RemoveViewportInformation(std::string(panelName.asChar())); _renderPanelCallbacks.erase(foundPanelCallbacks); } @@ -973,6 +1001,21 @@ MStatus MtohRenderOverride::setup(const MString& destination) newCallbacks.append(id); } + //Get information from viewport + std::string cameraName; + + M3dView view; + if (M3dView::getM3dViewFromModelPanel(destination, view)){//destination is a panel name + MDagPath dpath; + view.getCamera(dpath); + MFnCamera viewCamera(dpath); + cameraName = viewCamera.name().asChar(); + } + + //Create an HydraViewportInformation + const Fvp::InformationInterface::ViewportInformation hydraViewportInformation(std::string(destination.asChar()), cameraName); + Fvp::ViewportInformationAndSceneIndicesPerViewportDataManager::Get().AddViewportInformation(hydraViewportInformation); + _renderPanelCallbacks.emplace_back(destination, newCallbacks); } diff --git a/lib/mayaHydra/mayaPlugin/renderOverride.h b/lib/mayaHydra/mayaPlugin/renderOverride.h index cbbaed8702..7e3d96a090 100644 --- a/lib/mayaHydra/mayaPlugin/renderOverride.h +++ b/lib/mayaHydra/mayaPlugin/renderOverride.h @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include @@ -138,11 +138,13 @@ class MtohRenderOverride : public MHWRender::MRenderOverride static MtohRenderOverride* _GetByName(TfToken rendererName); - void _InitHydraResources(); + void _InitHydraResources(const MHWRender::MDrawContext& drawContext); void _RemovePanel(MString panelName); void _DetectMayaDefaultLighting(const MHWRender::MDrawContext& drawContext); HdRenderDelegate* _GetRenderDelegate(); void _SetRenderPurposeTags(const MayaHydraParams& delegateParams); + void _CreateSceneIndicesChainAfterMergingSceneIndex(); + void _UpdateRenderIndexProxyIfRequired(const MHWRender::MDrawContext& drawContext); void _PickByRegion( HdxPickHitVector& outHits, @@ -218,7 +220,7 @@ class MtohRenderOverride : public MHWRender::MRenderOverride HdRendererPlugin* _rendererPlugin = nullptr; HdxTaskController* _taskController = nullptr; HdPluginRenderDelegateUniqueHandle _renderDelegate = nullptr; - std::unique_ptr _renderIndexProxy; + Fvp::RenderIndexProxyPtr _renderIndexProxy{nullptr}; HdRenderIndex* _renderIndex = nullptr; Fvp::SelectionTrackerSharedPtr _fvpSelectionTracker; Fvp::SelectionSceneIndexRefPtr _selectionSceneIndex; diff --git a/plugin/mayaHydraSceneBrowser/mayaHydraSceneBrowser.cpp b/plugin/mayaHydraSceneBrowser/mayaHydraSceneBrowser.cpp index 6aa59c6c9b..cc111fb120 100644 --- a/plugin/mayaHydraSceneBrowser/mayaHydraSceneBrowser.cpp +++ b/plugin/mayaHydraSceneBrowser/mayaHydraSceneBrowser.cpp @@ -15,7 +15,7 @@ #include "mayaHydraSceneBrowser.h" #include -#include +#include #include diff --git a/plugin/mayaHydraSceneBrowserTest/mayaHydraSceneBrowserTestCmd.cpp b/plugin/mayaHydraSceneBrowserTest/mayaHydraSceneBrowserTestCmd.cpp index 0f170a805d..394481b53a 100644 --- a/plugin/mayaHydraSceneBrowserTest/mayaHydraSceneBrowserTestCmd.cpp +++ b/plugin/mayaHydraSceneBrowserTest/mayaHydraSceneBrowserTestCmd.cpp @@ -16,7 +16,7 @@ #include "mayaHydraSceneBrowserTestCmd.h" #include -#include +#include #include #include diff --git a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt index 78093c7da4..e614f5a072 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt @@ -20,6 +20,7 @@ set(TEST_SCRIPT_FILES cpp/testMergingSceneIndex.py cpp/testSelectionSceneIndex.py cpp/testWireframeSelectionHighlightSceneIndex.py + cpp/testFlowViewportAPIViewportInformation.py ) # Test use of mesh adapter code for mesh support, using environment variable. diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt index 995523b5ae..f59cd60821 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt @@ -20,6 +20,8 @@ target_sources(${TARGET_NAME} testSelectionSceneIndex.cpp testUtils.cpp testWireframeSelectionHighlightSceneIndex.cpp + testFvpViewportInformationMultipleViewports.cpp + testFvpViewportInformationRendererSwitching.cpp ) # ----------------------------------------------------------------------------- diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/infoClientTest.h b/test/lib/mayaUsd/render/mayaToHydra/cpp/infoClientTest.h new file mode 100644 index 0000000000..4a7feaf216 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/infoClientTest.h @@ -0,0 +1,51 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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 MAYATOHYDRA_CPP_INFO_CLIENT_TEST +#define MAYATOHYDRA_CPP_INFO_CLIENT_TEST + + +//Flow viewport headers +#include +#include + +//Subclass Fvp::InformationClient to register this class to receive callbacks. +class InfoClientTest : public Fvp::InformationClient +{ +public: + InfoClientTest() = default; + ~InfoClientTest() override = default; + + //From Fvp::InformationClient + void SceneIndexAdded(const Fvp::InformationInterface::ViewportInformation& viewportInformation)override + { + ++_numSceneIndexAdded;//We want to count the number of times this is called + } + + void SceneIndexRemoved(const Fvp::InformationInterface::ViewportInformation& viewportInformation)override + { + ++_numSceneIndexRemoved;//We want to count the number of times this is called + } + + int GetSceneIndexAdded() const {return _numSceneIndexAdded;} + int GetSceneIndexRemoved() const{return _numSceneIndexRemoved;} + +protected: + int _numSceneIndexAdded = 0; + int _numSceneIndexRemoved = 0; +}; + +#endif //MAYATOHYDRA_CPP_INFO_CLIENT_TEST \ No newline at end of file diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testFlowViewportAPIViewportInformation.py b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFlowViewportAPIViewportInformation.py new file mode 100644 index 0000000000..7a7520194d --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFlowViewportAPIViewportInformation.py @@ -0,0 +1,72 @@ +# +# Copyright 2023 Autodesk, Inc. All rights reserved. +# +# 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. +# + +import maya.cmds as cmds +import fixturesUtils +import mtohUtils +from testUtils import PluginLoaded +import maya.mel as mel + +class TestFlowViewportAPIViewportInformation(mtohUtils.MayaHydraBaseTestCase): + # MayaHydraBaseTestCase.setUpClass requirement. + _file = __file__ + + def test_RendererSwitching(self): + with PluginLoaded('mayaHydraCppTests'): + #Switch to Storm + self.setHdStormRenderer() + cmds.refresh() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationWithHydra") + #Switch to VP2 + self.setViewport2Renderer() + cmds.refresh() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationWithoutHydra") + #Switch to Storm again + self.setHdStormRenderer() + cmds.refresh() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationWithHydraAgain") + + def test_MultipleViewports(self): + with PluginLoaded('mayaHydraCppTests'): + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationMultipleViewportsInit") + #switch to 4 views + mel.eval('FourViewLayout') + #Set focus on persp view + cmds.setFocus ('modelPanel4') #Is the persp view + #Set Storm as the renderer + self.setHdStormRenderer() + + #Set focus on model Panel 2 (it's an orthographic view : right) + cmds.setFocus ('modelPanel2') + #Set Storm as the renderer + self.setHdStormRenderer() + cmds.refresh() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationMultipleViewports2Viewports") + + #Set focus on persp view + cmds.setFocus ('modelPanel4') #Is the persp view + #Set VP2 as the renderer + self.setViewport2Renderer() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationMultipleViewports1Viewport") + + #Set focus on model Panel 2 (it's an orthographic view : right) + cmds.setFocus ('modelPanel2') + #Set VP2 as the renderer + self.setViewport2Renderer() + cmds.mayaHydraCppTest(f="FlowViewportAPI.viewportInformationMultipleViewports0Viewport") + +if __name__ == '__main__': + fixturesUtils.runTests(globals()) diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationMultipleViewports.cpp b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationMultipleViewports.cpp new file mode 100644 index 0000000000..c60f857e80 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationMultipleViewports.cpp @@ -0,0 +1,120 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + +//Local headers +#include "testUtils.h" +#include "infoClientTest.h" + +//Google tests +#include + +namespace { + //Is a global instance + std::shared_ptr _infoClientTest; + + //Storm renderer name + const std::string _stormRendererName ("GL"); +} + +//The test is done through 4 Steps in the python script testFlowViewportAPIViewportInformation.py function test_MultipleViewports + +//Step 1) The python script calls viewportInformationMultipleViewportsInit before anything is done. +TEST(FlowViewportAPI, viewportInformationMultipleViewportsInit) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Register our callbacks client + _infoClientTest = std::make_shared(); + informationInterface.RegisterInformationClient(_infoClientTest); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportsInformation; + informationInterface.GetViewportsInformation(allViewportsInformation); + ASSERT_EQ(allViewportsInformation.size(), (size_t)0);//We should have 0 hydra viewport + + //Check initial count for _infoClientTest callbacks + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 0); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 0); + + //We don't call UnregisterInformationClient on purpose as we want to check if the callbacks are called and will unregister it in the code below +} + +//Step 2 : The python script has created 4 viewports and 2 are set to Storm +//and _infoClientTest is registered in Fvp::InformationInterface so InfoClientTest::SceneIndexAdded should be have been called twice +//then it calls viewportInformationMultipleViewports2Viewports +TEST(FlowViewportAPI, viewportInformationMultipleViewports2Viewports) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportsInformation; + informationInterface.GetViewportsInformation(allViewportsInformation); + ASSERT_EQ(allViewportsInformation.size(), (size_t)2); //we should have 2 Hydra viewports + + //Check renderers name, they all should be Storm + for (auto info : allViewportsInformation){ + ASSERT_EQ(info._rendererName, _stormRendererName); + } + + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 2);//Has been called twice + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 0); +} + +//Step 3 : the python script removed hydra from 1 of the 2 viewports +//and _infoClientTest is registered in Fvp::InformationInterface so InfoClientTest::SceneIndexRemoved should be have been called once +//then it calls viewportInformationMultipleViewports1Viewport +TEST(FlowViewportAPI, viewportInformationMultipleViewports1Viewport) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportsInformation; + informationInterface.GetViewportsInformation(allViewportsInformation); + ASSERT_EQ(allViewportsInformation.size(), (size_t)1);//We should have 1 hydra viewport + + //Check renderers name, they all should be Storm + for (auto info : allViewportsInformation){ + ASSERT_EQ(info._rendererName, _stormRendererName); + } + + //Both should have been called once only + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 2); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 1); +} + +//Step 4 : the python script removed hydra from the last viewport where hydra was +//and _infoClientTest is registered in Fvp::InformationInterface so InfoClientTest::SceneIndexRemoved should be have been called once again +//then it calls viewportInformationMultipleViewports0Viewport +TEST(FlowViewportAPI, viewportInformationMultipleViewports0Viewport) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportsInformation; + informationInterface.GetViewportsInformation(allViewportsInformation); + ASSERT_EQ(allViewportsInformation.size(), (size_t)0);//We should not have any hydra viewport + + ///Both should have been called once only + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 2); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 2); + + //Unregister our callbacks client + informationInterface.UnregisterInformationClient(_infoClientTest); +} diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationRendererSwitching.cpp b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationRendererSwitching.cpp new file mode 100644 index 0000000000..19fe2dc593 --- /dev/null +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testFvpViewportInformationRendererSwitching.cpp @@ -0,0 +1,104 @@ +// +// Copyright 2023 Autodesk, Inc. All rights reserved. +// +// 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. +// + +//Local headers +#include "testUtils.h" +#include "infoClientTest.h" + +//Google tests +#include + +namespace { + //Is a global instance + std::shared_ptr _infoClientTest; + + //Storm renderer name + const std::string _stormRendererName ("GL"); +} + +//The test is done through 3 Steps in the python script testFlowViewportAPIViewportInformation.py, function test_RendererSwitching + +//Step 1) The python script sets Storm as the renderer for the viewport then call viewportInformationWithHydra +//This is with Hydra, Storm should be the current renderer +TEST(FlowViewportAPI, viewportInformationWithHydra) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Register our callbacks client + _infoClientTest = std::make_shared(); + informationInterface.RegisterInformationClient(_infoClientTest); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportInformation; + informationInterface.GetViewportsInformation(allViewportInformation); + ASSERT_EQ(allViewportInformation.size(), (size_t)1);//We should have 1 hydra viewport + + //Check renderer name + auto it = allViewportInformation.cbegin(); + ASSERT_NE(it, allViewportInformation.cend()); + ASSERT_EQ(it->_rendererName, _stormRendererName); + + //Check initial count for _infoClientTest callbacks + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 0); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 0); + + //We don't call UnregisterInformationClient on purpose as we want to check if the callbacks are called and will unregister it in the code below +} + +//Step 2 : the python script sets VP2 as the renderer for the viewport then call viewportInformationWithoutHydra +//and _infoClientTest is registered in Fvp::InformationInterface so InfoClientTest::SceneIndexRemoved should be called when switching from Storm to VP2 +//This is without Hydra, VP2 should be the current renderer +TEST(FlowViewportAPI, viewportInformationWithoutHydra) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportInformation; + informationInterface.GetViewportsInformation(allViewportInformation); + ASSERT_EQ(allViewportInformation.size(), (size_t)0); //we should have no Hydra viewports + + //Only SceneIndexRemoved should have been called once + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 0); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 1); +} + +//Step 3 : the python script sets Storm again as the renderer for the viewport then call viewportInformationWithHydraAgain +//and _infoClientTest is still registered in Fvp::InformationInterface so InfoClientTest::SceneIndexAdded should be called when switching from VP2 to Storm +//This is with Hydra again, Storm should be the current renderer +TEST(FlowViewportAPI, viewportInformationWithHydraAgain) +{ + //Get Information interface + Fvp::InformationInterface& informationInterface = Fvp::InformationInterface::Get(); + + //Get all Hydra viewports information + Fvp::InformationInterface::ViewportInformationSet allViewportInformation; + informationInterface.GetViewportsInformation(allViewportInformation); + ASSERT_EQ(allViewportInformation.size(), (size_t)1);//We should have 1 hydra viewport + + //Check renderer name + auto it = allViewportInformation.cbegin(); + ASSERT_NE(it, allViewportInformation.cend()); + ASSERT_EQ(it->_rendererName, _stormRendererName); + + //Both should have been called once only + ASSERT_EQ(_infoClientTest->GetSceneIndexAdded(), 1); + ASSERT_EQ(_infoClientTest->GetSceneIndexRemoved(), 1); + + //Unregister our callbacks client + informationInterface.UnregisterInformationClient(_infoClientTest); +} diff --git a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp index 19df5b7f36..b1d244adbc 100644 --- a/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp +++ b/test/lib/mayaUsd/render/mayaToHydra/cpp/testUtils.cpp @@ -17,7 +17,7 @@ #include "testUtils.h" #include -#include +#include #include #include