Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HYDRA-1036 : Refactor Repr Selector Scene Index to send Dirty Notification #153

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
Loading