-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HYDRA-599 : Add data producer scene index interface in viewport API
- Loading branch information
1 parent
396c290
commit ba3b9b4
Showing
73 changed files
with
3,607 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
lib/flowViewport/API/fvpDataProducerSceneIndexInterface.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// | ||
// 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_DATA_PRODUCER_SCENE_INDEX_INTERFACE_H | ||
#define FLOW_VIEWPORT_API_DATA_PRODUCER_SCENE_INDEX_INTERFACE_H | ||
|
||
//Local headers | ||
#include "flowViewport/api.h" | ||
|
||
//Hydra headers | ||
#include <pxr/imaging/hd/sceneIndex.h> | ||
|
||
namespace FVP_NS_DEF | ||
{ | ||
/** | ||
* Interface to manage data producer scene indices in an Hydra viewport. A data producer scene index is a scene index that adds primitives to the current rendering. | ||
* These new primitives are created without the need of a DCC object or a USD stage. | ||
* To get an instance of the DataProducerSceneIndexInterface class, please use : | ||
* Fvp::DataProducerSceneIndexInterface& dataProducerSceneIndexInterface = Fvp::DataProducerSceneIndexInterface::get(); | ||
*/ | ||
class DataProducerSceneIndexInterface | ||
{ | ||
public: | ||
|
||
/// Interface accessor | ||
static FVP_API DataProducerSceneIndexInterface& get(); | ||
|
||
/// Use this string in the viewport identifier parameters, named "hydraViewportId" in this class, to apply the data producer scene index to all viewports. | ||
static FVP_API const std::string allViewports; | ||
|
||
/// Use this string in the AddDataProducerSceneIndex method for the "rendererNames" parameter to apply to all renderers. | ||
static FVP_API const std::string allRenderers; | ||
|
||
/** | ||
* @brief Adds a custom data producer scene index. | ||
* | ||
* Adds a custom data producer scene index and associate it to be used in the same rendering as the hydra viewport whose identifier is hydraViewportId | ||
* (or all hydra viewports if hydraViewportId is DataProducerSceneIndexInterface::allViewports). | ||
* Basically, we merge this scene index with the others scene indices from the viewport which are the usd stages, the DCC native | ||
* data and any others custom data producer scene indices like this one. | ||
* | ||
* @param[in] customDataProducerSceneIndex is the custom scene index to add. | ||
* | ||
* @param[in] dccNode is a MObject* for Maya or an INode* for 3ds max, 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. | ||
* | ||
* @param[in] hydraViewportId is an hydra viewport string identifier to which _customDataProducerSceneIndex needs to be associated to. | ||
* Set it to DataProducerSceneIndexInterface::allViewports to add this data producer scene index to all viewports. | ||
* To retrieve a specific hydra viewport identifier, please use the InformationInterface class. | ||
* | ||
* @param[in] rendererNames : are the Hydra renderer names to which this scene index should be added. | ||
* 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. | ||
* | ||
* @param[in] customDataProducerSceneIndexRootPathForInsertion is the root path for insertion used as a second parameter of HdRenderIndex::InsertSceneIndex method. | ||
* e.g : renderIndex.InsertSceneIndex(_customDataProducerSceneIndex, _customDataProducerSceneIndexRootPathForInsertion); | ||
* | ||
*/ | ||
virtual void addDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, | ||
void* dccNode = nullptr, | ||
const std::string& hydraViewportId = allViewports, | ||
const std::string& rendererNames = allRenderers, | ||
const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion = PXR_NS::SdfPath::AbsoluteRootPath() | ||
) = 0; | ||
|
||
/** | ||
* @brief Removes a custom data producer scene index. | ||
* | ||
* Removes a custom data producer scene index, this scene index will not participate any more to the rendering of the given viewport(s). | ||
* | ||
* @param[in] customDataProducerSceneIndex is the custom scene index to remove. | ||
* | ||
* @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 = allViewports | ||
) = 0; | ||
}; | ||
|
||
}//end of namespace FVP_NS_DEF | ||
|
||
#endif //FLOW_VIEWPORT_API_DATA_PRODUCER_SCENE_INDEX_INTERFACE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
230 changes: 230 additions & 0 deletions
230
lib/flowViewport/API/interfacesImp/fvpDataProducerSceneIndexInterfaceImp.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
// | ||
// 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 "fvpDataProducerSceneIndexInterfaceImp.h" | ||
#include "fvpInformationInterfaceImp.h" | ||
#include "flowViewport/API/perViewportSceneIndicesData/fvpViewportInformationAndSceneIndicesPerViewportDataManager.h" | ||
#include "flowViewport/sceneIndex/fvpRenderIndexProxy.h" | ||
|
||
//Hydra headers | ||
#include <pxr/imaging/hd/renderIndex.h> | ||
|
||
//STL Headers | ||
#include <mutex> | ||
|
||
namespace | ||
{ | ||
std::mutex _dataProducerSceneIndicesThatApplyToAllViewports_mutex; | ||
|
||
// Are the scene indices that need to be applied to all viewports | ||
std::set<PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr> _dataProducerSceneIndicesThatApplyToAllViewports; | ||
|
||
// Abstract factory to create the scene index data, an implementation is provided by the DCC | ||
FVP_NS::DataProducerSceneIndexDataAbstractFactory* _sceneIndexDataFactory{nullptr}; | ||
} | ||
|
||
PXR_NAMESPACE_USING_DIRECTIVE | ||
|
||
namespace FVP_NS_DEF { | ||
|
||
const std::string DataProducerSceneIndexInterface::allViewports = "allViewports"; | ||
const std::string DataProducerSceneIndexInterface::allRenderers = "allRenderers"; | ||
|
||
DataProducerSceneIndexInterface& DataProducerSceneIndexInterface::get() | ||
{ | ||
return DataProducerSceneIndexInterfaceImp::get(); | ||
} | ||
|
||
DataProducerSceneIndexInterfaceImp& DataProducerSceneIndexInterfaceImp::get() | ||
{ | ||
static DataProducerSceneIndexInterfaceImp theInterface; | ||
return theInterface; | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::addDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, | ||
void* dccNode /*= nullptr*/, | ||
const std::string& hydraViewportId /*= allViewports*/, | ||
const std::string& rendererNames /*= allRenderers*/, | ||
const PXR_NS::SdfPath& customDataProducerSceneIndexRootPathForInsertion /*= PXR_NS::SdfPath::AbsoluteRootPath()*/) | ||
{ | ||
//_viewportSceneIndex can be a reference on a nullptr meaning the user wants _customDataProducerSceneIndex to be applied in all viewports. | ||
PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexData = | ||
_CreateDataProducerSceneIndexData(customDataProducerSceneIndex, rendererNames, customDataProducerSceneIndexRootPathForInsertion, dccNode); | ||
|
||
if (DataProducerSceneIndexInterface::allViewports == hydraViewportId){ | ||
//Apply this dataProducer scene index to all viewports | ||
_AddDataProducerSceneIndexToAllViewports(dataProducerSceneIndexData); | ||
} else{ | ||
//Apply this dataProducer scene index to a single viewport | ||
const ViewportInformationAndSceneIndicesPerViewportData* viewportInfoAndData = | ||
ViewportInformationAndSceneIndicesPerViewportDataManager::Get().GetViewportInfoAndDataFromViewportId(hydraViewportId); | ||
if (viewportInfoAndData){ | ||
_AddDataProducerSceneIndexToThisViewport(viewportInfoAndData->GetViewportInformation(), dataProducerSceneIndexData); | ||
} | ||
} | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::removeAllViewportDataProducerSceneIndices(ViewportInformationAndSceneIndicesPerViewportData& viewportInformationAndSceneIndicesPerViewportData) | ||
{ | ||
auto& renderIndexProxy = viewportInformationAndSceneIndicesPerViewportData.GetRenderIndexProxy(); | ||
if(nullptr == renderIndexProxy){ | ||
return; | ||
} | ||
|
||
auto& dataProducerSceneIndicesDataForthisViewport = viewportInformationAndSceneIndicesPerViewportData.GetDataProducerSceneIndicesData(); | ||
|
||
for (auto& dataProducerSceneIndicesData : dataProducerSceneIndicesDataForthisViewport){ | ||
//Remove it from the render index | ||
if (dataProducerSceneIndicesData){ | ||
const auto& sceneIndex = dataProducerSceneIndicesData->GetDataProducerLastSceneIndexChain(); | ||
if (sceneIndex){ | ||
renderIndexProxy->RemoveSceneIndex(sceneIndex); | ||
}else{ | ||
TF_CODING_ERROR("dataProducerSceneIndexData->GetDataProducerLastSceneIndexChain() is a nullptr, that should never happen here."); | ||
} | ||
} | ||
} | ||
|
||
dataProducerSceneIndicesDataForthisViewport.clear(); | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::removeViewportDataProducerSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, | ||
const std::string& hydraViewportId /*= allViewports*/) | ||
{ | ||
if (DataProducerSceneIndexInterface::allViewports == hydraViewportId){ | ||
//It was applied to all viewports | ||
|
||
ViewportInformationAndSceneIndicesPerViewportDataSet& allViewportsInfoAndSceneIndices = | ||
ViewportInformationAndSceneIndicesPerViewportDataManager::Get().GetAllViewportInfoAndData(); | ||
|
||
//We need to remove it from all viewports where it was applied. | ||
for (auto& viewportInfoAndData : allViewportsInfoAndSceneIndices){ | ||
ViewportInformationAndSceneIndicesPerViewportData& nonConstViewportInfoAndData = const_cast<ViewportInformationAndSceneIndicesPerViewportData&>(viewportInfoAndData); | ||
nonConstViewportInfoAndData.RemoveViewportDataProducerSceneIndex(customDataProducerSceneIndex); | ||
} | ||
|
||
//Also remove it from the _dataProducerSceneIndicesThatApplyToAllViewports array | ||
auto findResult = std::find_if(_dataProducerSceneIndicesThatApplyToAllViewports.begin(), _dataProducerSceneIndicesThatApplyToAllViewports.end(), | ||
[&customDataProducerSceneIndex](const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSIData) { | ||
return (dataProducerSIData && dataProducerSIData->GetDataProducerSceneIndex() == customDataProducerSceneIndex);} | ||
); | ||
if (findResult != _dataProducerSceneIndicesThatApplyToAllViewports.end()){ | ||
_dataProducerSceneIndicesThatApplyToAllViewports.erase(findResult);// Which also decreases ref count | ||
} | ||
}else{ | ||
//It was applied to a single viewport | ||
auto viewportInformationAndSceneIndicesPerViewportData = ViewportInformationAndSceneIndicesPerViewportDataManager::Get().GetViewportInfoAndDataFromViewportId(hydraViewportId); | ||
viewportInformationAndSceneIndicesPerViewportData->RemoveViewportDataProducerSceneIndex(customDataProducerSceneIndex); | ||
} | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::_AddDataProducerSceneIndexToAllViewports(const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSceneIndexData) | ||
{ | ||
//Remove const from _dataProducerSceneIndexData | ||
PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr dataProducerSceneIndexDataNonConst = dataProducerSceneIndexData; | ||
|
||
//This is a block for the mutex lifetime | ||
{ | ||
std::lock_guard<std::mutex> lockDataProducerSceneIndicesDataPerViewport(_dataProducerSceneIndicesThatApplyToAllViewports_mutex); | ||
|
||
//Check if it is already inside our array | ||
auto findResult = _dataProducerSceneIndicesThatApplyToAllViewports.find(dataProducerSceneIndexDataNonConst); | ||
if (findResult != _dataProducerSceneIndicesThatApplyToAllViewports.cend()){ | ||
return; | ||
} | ||
|
||
//It is not already in dataProducerSceneIndexDataSet | ||
//Add it with the dataProducer scene indices that need to be applied to all viewports | ||
_dataProducerSceneIndicesThatApplyToAllViewports.insert(dataProducerSceneIndexDataNonConst); | ||
} | ||
|
||
//Apply it to all existing hydra viewports | ||
InformationInterface::ViewportInformationSet viewportsInformation; | ||
InformationInterfaceImp::Get().GetViewportsInformation(viewportsInformation); | ||
for (const auto& viewportInfo : viewportsInformation){ | ||
_AddDataProducerSceneIndexToThisViewport(viewportInfo, dataProducerSceneIndexData); | ||
} | ||
} | ||
|
||
PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr DataProducerSceneIndexInterfaceImp::_CreateDataProducerSceneIndexData(const HdSceneIndexBaseRefPtr& customDataProducerSceneIndex, | ||
const std::string& rendererNames, | ||
const SdfPath& customDataProducerSceneIndexRootPathForInsertion, | ||
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; | ||
} | ||
|
||
const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBase::CreationParameters params(customDataProducerSceneIndex, rendererNames, customDataProducerSceneIndexRootPathForInsertion, dccNode); | ||
return _sceneIndexDataFactory->createDataProducerSceneIndexDataBase(params); | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::_AddDataProducerSceneIndexToThisViewport(const InformationInterface::ViewportInformation& viewportInformation, | ||
const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSceneIndexData) | ||
{ | ||
TF_AXIOM(dataProducerSceneIndexData); | ||
|
||
const std::string& hydraViewportId = viewportInformation._viewportId; | ||
TF_AXIOM(hydraViewportId.length() > 0); | ||
|
||
//Check if there is some filtering per Hydra renderer | ||
const std::string& viewportRendererName = viewportInformation._rendererName; | ||
const std::string& dataProducerSceneIndexApplyToRendererNames = dataProducerSceneIndexData->GetRendererNames(); | ||
if ( (! viewportRendererName.empty() )&& (dataProducerSceneIndexApplyToRendererNames != DataProducerSceneIndexInterface::allRenderers) ){ | ||
//Filtering per renderer is applied | ||
if (std::string::npos == dataProducerSceneIndexApplyToRendererNames.find(viewportRendererName)){ | ||
return; //Ignore the current hydra viewport renderer name is not part of the supported renderers for this dataProducer scene index | ||
} | ||
} | ||
|
||
ViewportInformationAndSceneIndicesPerViewportData* viewportInformationAndSceneIndicesPerViewportData = | ||
ViewportInformationAndSceneIndicesPerViewportDataManager::Get().GetViewportInfoAndDataFromViewportId(hydraViewportId); | ||
TF_AXIOM(viewportInformationAndSceneIndicesPerViewportData ); | ||
|
||
auto& dataProducerSceneIndicesDataForthisViewport = viewportInformationAndSceneIndicesPerViewportData->GetDataProducerSceneIndicesData(); | ||
auto findResult = dataProducerSceneIndicesDataForthisViewport.find(dataProducerSceneIndexData); | ||
if (findResult != dataProducerSceneIndicesDataForthisViewport.end()){ | ||
return; //Already in our array | ||
} | ||
|
||
dataProducerSceneIndicesDataForthisViewport.insert(dataProducerSceneIndexData);//dataProducerSceneIndexData can be shared between multiple viewports | ||
|
||
//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()); | ||
} | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::hydraViewportSceneIndexAdded(const InformationInterface::ViewportInformation& viewportInfo) | ||
{ | ||
//Add the dataProducer scene indices that apply to all viewports to this newly created hydra viewport | ||
std::lock_guard<std::mutex> lockDataProducerSceneIndicesDataPerViewport(_dataProducerSceneIndicesThatApplyToAllViewports_mutex); | ||
for (const PXR_NS::FVP_NS_DEF::DataProducerSceneIndexDataBaseRefPtr& dataProducerSceneIndexData : _dataProducerSceneIndicesThatApplyToAllViewports){ | ||
_AddDataProducerSceneIndexToThisViewport(viewportInfo, dataProducerSceneIndexData); | ||
} | ||
} | ||
|
||
void DataProducerSceneIndexInterfaceImp::setSceneIndexDataFactory(DataProducerSceneIndexDataAbstractFactory& factory) | ||
{ | ||
_sceneIndexDataFactory = &factory; | ||
} | ||
|
||
} //End of namespace FVP_NS_DEF |
Oops, something went wrong.