Skip to content

Commit

Permalink
HYDRA-1036 : Refactor Repr Selector Scene Index to send Dirty Notific…
Browse files Browse the repository at this point in the history
…ation (#153)

* First commit to introduce changes to allow Hydra prim dirtying instead of repeated Add/Removal of prims

* minor tweaks

* Misc changes

* Improvement to repr switch logic. Added comments. Misc cleanup

* Add default case

* Addressed an issue where refinement adjustment was not captured

* Add test case

* Change type from uint to int for Linux gcc compatibility

* style changes

* Style change for linux again
  • Loading branch information
roopavr-adsk authored Jul 30, 2024
1 parent a43749c commit e42b8e7
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 61 deletions.
43 changes: 35 additions & 8 deletions lib/flowViewport/sceneIndex/fvpReprSelectorSceneIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <pxr/imaging/hd/containerDataSourceEditor.h>
#include <pxr/imaging/hd/legacyDisplayStyleSchema.h>
#include <pxr/imaging/hd/primvarsSchema.h>

#include <pxr/imaging/hd/sceneIndexPrimView.h>

// This class is a filtering scene index that that applies a different RepSelector on geometries (such as wireframe or wireframe on shaded)
// and also applies an overrideWireframecolor for HdStorm
Expand Down Expand Up @@ -73,30 +73,59 @@ const HdRetainedContainerDataSourceHandle sWireframeDisplayStyleDataSource

}//End of namespace

ReprSelectorSceneIndex::ReprSelectorSceneIndex(const HdSceneIndexBaseRefPtr& inputSceneIndex, RepSelectorType type, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface)
ReprSelectorSceneIndex::ReprSelectorSceneIndex(const HdSceneIndexBaseRefPtr& inputSceneIndex, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface)
: ParentClass(inputSceneIndex),
InputSceneIndexUtils(inputSceneIndex),
_wireframeColorInterface(wireframeColorInterface)
{
TF_AXIOM(_wireframeColorInterface);
switch (type){
}

void ReprSelectorSceneIndex::SetReprType(RepSelectorType reprType, bool needsReprChanged, int refineLevel)
{
switch (reprType){
case RepSelectorType::WireframeRefined:
_wireframeTypeDataSource = sWireframeDisplayStyleDataSource;
break;
case RepSelectorType::WireframeOnSurface:
_wireframeTypeDataSource = sdWireframeOnShadedDisplayStyleDataSource;
break;
case RepSelectorType::WireframeOnSurfaceRefined:
_wireframeTypeDataSource = sRefinedWireframeOnShadedDisplayStyleDataSource;
if (refineLevel > 0)
_wireframeTypeDataSource = sRefinedWireframeOnShadedDisplayStyleDataSource;
else
_wireframeTypeDataSource = sdWireframeOnShadedDisplayStyleDataSource;
break;
case RepSelectorType::Default:
break;
}

const HdDataSourceLocatorSet locators{
HdLegacyDisplayStyleSchema::GetDefaultLocator(),
HdPrimvarsSchema::GetDefaultLocator(),
HdLegacyDisplayStyleSchema::GetDefaultLocator()
};
_needsReprChanged = needsReprChanged;
_DirtyAllPrims(locators);
}

void
ReprSelectorSceneIndex::_DirtyAllPrims(
const HdDataSourceLocatorSet locators)
{
HdSceneIndexObserver::DirtiedPrimEntries entries;
for (const SdfPath &path : HdSceneIndexPrimView(GetInputSceneIndex())) {
entries.push_back({path, locators});
}
_SendPrimsDirtied(entries);
}

HdSceneIndexPrim ReprSelectorSceneIndex::GetPrim(const SdfPath& primPath) const
{
HdSceneIndexPrim prim = GetInputSceneIndex()->GetPrim(primPath);
if (prim.dataSource && !_isExcluded(primPath) && (prim.primType == HdPrimTypeTokens->mesh) ){

if ( (prim.dataSource && !_isExcluded(primPath)) &&
(prim.primType == HdPrimTypeTokens->mesh) && _needsReprChanged ) {

//Edit the dataSource as an overlay will not replace any existing attribute value.
// So we need to edit the _primVarsTokens->overrideWireframeColor attribute as they may already exist in the prim
auto edited = HdContainerDataSourceEditor(prim.dataSource);
Expand All @@ -111,10 +140,8 @@ HdSceneIndexPrim ReprSelectorSceneIndex::GetPrim(const SdfPath& primPath) const
//Edit the cull style
edited.Set(HdLegacyDisplayStyleSchema::GetCullStyleLocator(),
HdRetainedTypedSampledDataSource<TfToken>::New(HdCullStyleTokens->nothing));//No culling

prim.dataSource = HdOverlayContainerDataSource::New({ edited.Finish(), _wireframeTypeDataSource});
}

return prim;
}

Expand Down
13 changes: 10 additions & 3 deletions lib/flowViewport/sceneIndex/fvpReprSelectorSceneIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ class ReprSelectorSceneIndex : public PXR_NS::HdSingleInputFilteringSceneIndexBa
WireframeRefined, //Refined wireframe (refined means that it supports a "refineLevel" attribute in the displayStyle to get a more refined drawing, valid range is from 0 to 8)
WireframeOnSurface, //Wireframe on surface not refined
WireframeOnSurfaceRefined,//Wireframe on surface refined
Default, // Default shaded
};

FVP_API
static ReprSelectorSceneIndexRefPtr New(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, RepSelectorType type, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface){
return PXR_NS::TfCreateRefPtr(new ReprSelectorSceneIndex(inputSceneIndex, type, wireframeColorInterface));
static ReprSelectorSceneIndexRefPtr New(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface){
return PXR_NS::TfCreateRefPtr(new ReprSelectorSceneIndex(inputSceneIndex, wireframeColorInterface));
}

// From HdSceneIndexBase
Expand All @@ -70,10 +71,13 @@ class ReprSelectorSceneIndex : public PXR_NS::HdSingleInputFilteringSceneIndexBa
void addExcludedSceneRoot(const PXR_NS::SdfPath& sceneRoot) {
_excludedSceneRoots.emplace(sceneRoot);
}

FVP_API
void SetReprType(RepSelectorType reprType, bool needsReprChanged, int refineLevel);

protected:

ReprSelectorSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, RepSelectorType type, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface);
ReprSelectorSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, const std::shared_ptr<WireframeColorInterface>& wireframeColorInterface);

//From HdSingleInputFilteringSceneIndexBase
void _PrimsAdded(const PXR_NS::HdSceneIndexBase& sender, const PXR_NS::HdSceneIndexObserver::AddedPrimEntries& entries) override{
Expand All @@ -99,6 +103,9 @@ ReprSelectorSceneIndex(const PXR_NS::HdSceneIndexBaseRefPtr& inputSceneIndex, Re
}

std::set<PXR_NS::SdfPath> _excludedSceneRoots;

void _DirtyAllPrims(const PXR_NS::HdDataSourceLocatorSet locators);
bool _needsReprChanged {false};

PXR_NS::HdRetainedContainerDataSourceHandle _wireframeTypeDataSource = nullptr;
std::shared_ptr<WireframeColorInterface> _wireframeColorInterface;
Expand Down
94 changes: 45 additions & 49 deletions lib/mayaHydra/mayaPlugin/renderOverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,15 +684,14 @@ MStatus MtohRenderOverride::Render(
delegateParams.displaySmoothMeshes = !(currentDisplayStyle & MHWRender::MFrameContext::kFlatShaded);

const bool currentUseDefaultMaterial = (drawContext.getDisplayStyle() & MHWRender::MFrameContext::kDefaultMaterial);
const bool xRayEnabled = (drawContext.getDisplayStyle() & MHWRender::MFrameContext::kXray);

if (_mayaHydraSceneIndex) {
_mayaHydraSceneIndex->SetDefaultLightEnabled(_hasDefaultLighting);
_mayaHydraSceneIndex->SetDefaultLight(_defaultLight);
_mayaHydraSceneIndex->SetParams(delegateParams);
_mayaHydraSceneIndex->PreFrame(drawContext);

if (_NeedToRecreateTheSceneIndicesChain(currentDisplayStyle, xRayEnabled)){
if (_NeedToRecreateTheSceneIndicesChain(currentDisplayStyle)){
_blockPrimRemovalPropagationSceneIndex->setPrimRemovalBlocked(true);//Prevent prim removal propagation to keep the current selection.
//We need to recreate the filtering scene index chain after the merging scene index as there was a change such as in the BBox display style which has been turned on or off.
_lastFilteringSceneIndexBeforeCustomFiltering = nullptr;//Release
Expand All @@ -710,8 +709,6 @@ MStatus MtohRenderOverride::Render(
}
const Fvp::InformationInterface::ViewportInformation hydraViewportInformation(std::string(panelName.asChar()), cameraName);
manager.AddViewportInformation(hydraViewportInformation, _renderIndexProxy, _lastFilteringSceneIndexBeforeCustomFiltering);

_xRayEnabled = xRayEnabled;
_blockPrimRemovalPropagationSceneIndex->setPrimRemovalBlocked(false);//Allow prim removal propagation again.
}
}
Expand All @@ -738,6 +735,35 @@ MStatus MtohRenderOverride::Render(
_defaultMaterialSceneIndex->Enable(currentUseDefaultMaterial);
_useDefaultMaterial = currentUseDefaultMaterial;
}

// Set Required Hydra Repr (Wireframe/WireframeOnShaded/Shaded)
// Hydra supports Wireframe and WireframeOnSurfaceRefined repr for wireframe on shaded mode.
// Refinement level for Hydra is set in Hydra Render Globals
const MFrameContext::WireOnShadedMode wireOnShadedMode = MFrameContext::wireOnShadedMode();//Get the user preference
if ( (_reprSelectorSceneIndex && (currentDisplayStyle != _oldDisplayStyle) ) || (delegateParams.refineLevel != _oldRefineLevel)){
if( (currentDisplayStyle & MHWRender::MFrameContext::kWireFrame) &&
((currentDisplayStyle & MHWRender::MFrameContext::kGouraudShaded) ||
(currentDisplayStyle & MHWRender::MFrameContext::kTextured)) ) {
// Wireframe on top of shaded
if (MFrameContext::WireOnShadedMode::kWireframeOnShadedFull == wireOnShadedMode) {
_reprSelectorSceneIndex->SetReprType(Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeOnSurfaceRefined,
/*needsReprChanged=*/true, delegateParams.refineLevel);
} else {
_reprSelectorSceneIndex->SetReprType(Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeOnSurface,
/*needsReprChanged=*/true, delegateParams.refineLevel);
}
}
else if( (currentDisplayStyle & MHWRender::MFrameContext::kWireFrame) ) {
//wireframe only, not on top of shaded
_reprSelectorSceneIndex->SetReprType(Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeRefined,
/*needsReprChanged=*/true, delegateParams.refineLevel);
}
else // Shaded mode
_reprSelectorSceneIndex->SetReprType(Fvp::ReprSelectorSceneIndex::RepSelectorType::Default,
/*needsReprChanged=*/false, delegateParams.refineLevel);

_oldRefineLevel = delegateParams.refineLevel;
}

HdxRenderTaskParams params;
params.enableLighting = true;
Expand Down Expand Up @@ -1051,7 +1077,8 @@ void MtohRenderOverride::ClearHydraResources(bool fullReset)
_selection.reset();
_wireframeColorInterfaceImp.reset();
_leadObjectPathTracker.reset();

_oldDisplayStyle = 0;
_oldRefineLevel = 0;
// Cleanup internal context data that keep references to data that is now
// invalid.
_engine.ClearTaskContextData();
Expand Down Expand Up @@ -1107,16 +1134,11 @@ void MtohRenderOverride::_CreateSceneIndicesChainAfterMergingSceneIndex(const MH
_mayaHydraSceneIndex ? _mayaHydraSceneIndex->GetDefaultMaterialExclusionPaths(): SdfPathVector());

const unsigned int currentDisplayStyle = drawContext.getDisplayStyle();
const MFrameContext::WireOnShadedMode wireOnShadedMode = MFrameContext::wireOnShadedMode();//Get the user preference

auto mergingSceneIndex = _renderIndexProxy->GetMergingSceneIndex();
if(! _leadObjectPathTracker){
_leadObjectPathTracker = std::make_shared<MAYAHYDRA_NS_DEF::MhLeadObjectPathTracker>(mergingSceneIndex, _dirtyLeadObjectSceneIndex);
}

if (! _wireframeColorInterfaceImp){
_wireframeColorInterfaceImp = std::make_shared<MAYAHYDRA_NS_DEF::MhWireframeColorInterfaceImp>(_selection, _leadObjectPathTracker);
}

//Are we using Bounding Box display style ?
if (currentDisplayStyle & MHWRender::MFrameContext::kBoundingBox){
Expand All @@ -1125,36 +1147,17 @@ void MtohRenderOverride::_CreateSceneIndicesChainAfterMergingSceneIndex(const MH
bboxSceneIndex->addExcludedSceneRoot(MAYA_NATIVE_ROOT); // Maya native prims are already converted by OGS
_lastFilteringSceneIndexBeforeCustomFiltering = bboxSceneIndex;
}
else if (currentDisplayStyle & MHWRender::MFrameContext::kWireFrame){//Are we using wireframe somehow ?

if( (currentDisplayStyle & MHWRender::MFrameContext::kGouraudShaded) || (currentDisplayStyle & MHWRender::MFrameContext::kTextured)){
// Wireframe on top of shaded
//Reduced quality
if (MFrameContext::WireOnShadedMode::kWireFrameOnShadedReduced == wireOnShadedMode ){
//Insert the reprselector filtering scene index which updates the repr selector on geometries
auto reprSelectorSceneIndex = Fvp::ReprSelectorSceneIndex::New(_lastFilteringSceneIndexBeforeCustomFiltering,
Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeOnSurface, _wireframeColorInterfaceImp);
reprSelectorSceneIndex->addExcludedSceneRoot(MAYA_NATIVE_ROOT); // Maya native prims are already converted by OGS
_lastFilteringSceneIndexBeforeCustomFiltering = reprSelectorSceneIndex;
} else {//Full quality
//Should we support kWireFrameOnShadedNone and do not display any wireframe ?
//Insert the reprselector filtering scene index which updates the repr selector on geometries
auto reprSelectorSceneIndex = Fvp::ReprSelectorSceneIndex::New(_lastFilteringSceneIndexBeforeCustomFiltering,
Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeOnSurfaceRefined, _wireframeColorInterfaceImp);
reprSelectorSceneIndex->addExcludedSceneRoot(MAYA_NATIVE_ROOT); // Maya native prims are already converted by OGS
_lastFilteringSceneIndexBeforeCustomFiltering = reprSelectorSceneIndex;
}
}
else{
//wireframe only, not on top of shaded

//Insert the reprselector filtering scene index which updates the repr selector on geometries
auto reprSelectorSceneIndex = Fvp::ReprSelectorSceneIndex::New(_lastFilteringSceneIndexBeforeCustomFiltering,
Fvp::ReprSelectorSceneIndex::RepSelectorType::WireframeRefined, _wireframeColorInterfaceImp);
reprSelectorSceneIndex->addExcludedSceneRoot(MAYA_NATIVE_ROOT); // Maya native prims are already converted by OGS
_lastFilteringSceneIndexBeforeCustomFiltering = reprSelectorSceneIndex;
}

if (! _wireframeColorInterfaceImp){
_wireframeColorInterfaceImp = std::make_shared<MAYAHYDRA_NS_DEF::MhWireframeColorInterfaceImp>(_selection, _leadObjectPathTracker);
}

// Repr selector Scene Index
_lastFilteringSceneIndexBeforeCustomFiltering = _reprSelectorSceneIndex =
Fvp::ReprSelectorSceneIndex::New(_lastFilteringSceneIndexBeforeCustomFiltering,
_wireframeColorInterfaceImp);
_reprSelectorSceneIndex->addExcludedSceneRoot(MAYA_NATIVE_ROOT);
_reprSelectorSceneIndex->SetReprType(Fvp::ReprSelectorSceneIndex::RepSelectorType::Default, false, _globals.delegateParams.refineLevel);

_wireframeSelectionHighlightSceneIndex = TfDynamic_cast<Fvp::WireframeSelectionHighlightSceneIndexRefPtr>(Fvp::WireframeSelectionHighlightSceneIndex::New(_lastFilteringSceneIndexBeforeCustomFiltering, _selection, _wireframeColorInterfaceImp));
_wireframeSelectionHighlightSceneIndex->SetDisplayName("Flow Viewport Wireframe Selection Highlight Scene Index");
Expand Down Expand Up @@ -1636,17 +1639,10 @@ void MtohRenderOverride::_RenderOverrideChangedCallback(
}

// return true if we need to recreate the filtering scene indices chain because of a change, false otherwise.
bool MtohRenderOverride::_NeedToRecreateTheSceneIndicesChain(unsigned int currentDisplayStyle, bool xRayEnabled)
bool MtohRenderOverride::_NeedToRecreateTheSceneIndicesChain(unsigned int currentDisplayStyle)
{
if (areDifferentForOneOfTheseBits(currentDisplayStyle, _oldDisplayStyle,
MHWRender::MFrameContext::kGouraudShaded |
MHWRender::MFrameContext::kWireFrame |
MHWRender::MFrameContext::kBoundingBox )
){
return true;
}

if (_xRayEnabled != xRayEnabled){
if (areDifferentForOneOfTheseBits(currentDisplayStyle, _oldDisplayStyle,
MHWRender::MFrameContext::kBoundingBox)){
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion lib/mayaHydra/mayaPlugin/renderOverride.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <flowViewport/sceneIndex/fvpDisplayStyleOverrideSceneIndex.h>
#include <flowViewport/sceneIndex/fvpPruneTexturesSceneIndex.h>
#include <flowViewport/sceneIndex/fvpDefaultMaterialSceneIndex.h>
#include <flowViewport/sceneIndex/fvpReprSelectorSceneIndex.h>
#include <flowViewport/sceneIndex/fvpBlockPrimRemovalPropagationSceneIndex.h>
#include <flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.h>

Expand Down Expand Up @@ -209,7 +210,7 @@ class MtohRenderOverride : public MHWRender::MRenderOverride,

void _AddPluginSelectionHighlighting();

bool _NeedToRecreateTheSceneIndicesChain(unsigned int currentDisplayStyle, bool xRayEnabled);
bool _NeedToRecreateTheSceneIndicesChain(unsigned int currentDisplayStyle);

// Determine the pick handler which should handle a pick hit, to transform
// the pick hit into a selection.
Expand Down Expand Up @@ -260,6 +261,7 @@ class MtohRenderOverride : public MHWRender::MRenderOverride,
HdSceneIndexBaseRefPtr _inputSceneIndexOfFilteringSceneIndicesChain {nullptr};
Fvp::DisplayStyleOverrideSceneIndexRefPtr _displayStyleSceneIndex;
Fvp::PruneTexturesSceneIndexRefPtr _pruneTexturesSceneIndex;
Fvp::ReprSelectorSceneIndexRefPtr _reprSelectorSceneIndex;
Fvp::DefaultMaterialSceneIndexRefPtr _defaultMaterialSceneIndex;
HdRenderIndex* _renderIndex = nullptr;
Fvp::SelectionTrackerSharedPtr _fvpSelectionTracker;
Expand Down Expand Up @@ -312,6 +314,7 @@ class MtohRenderOverride : public MHWRender::MRenderOverride,
bool _hasDefaultLighting = false;
bool _currentlyTextured = false;
unsigned int _oldDisplayStyle {0};
int _oldRefineLevel {0};
bool _useDefaultMaterial;
bool _xRayEnabled;
};
Expand Down
1 change: 1 addition & 0 deletions test/lib/mayaUsd/render/mayaToHydra/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ set(INTERACTIVE_TEST_SCRIPT_FILES
cpp/testPointInstancingWireframeHighlight.py
cpp/testGeomSubsetsPicking.py
cpp/testSinglePicking.py
cpp/testSceneIndexDirtying.py
cpp/testGeomSubsetsWireframeHighlight.py
)

Expand Down
1 change: 1 addition & 0 deletions test/lib/mayaUsd/render/mayaToHydra/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ target_sources(${TARGET_NAME}
testPointInstancingWireframeHighlight.cpp
testGeomSubsetsPicking.cpp
testSinglePicking.cpp
testSceneIndexDirtying.cpp
testGeomSubsetsWireframeHighlight.cpp
)

Expand Down
Loading

0 comments on commit e42b8e7

Please sign in to comment.