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-324: update proxy shape scene index to support interpret pick result #3028

94 changes: 79 additions & 15 deletions lib/mayaUsd/sceneIndex/proxyShapeSceneIndexPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,17 @@
#include <maya/MSelectionList.h>
#include <maya/MString.h>
#if WANT_UFE_BUILD
#include <mayaUsd/ufe/Utils.h>

#include <ufe/rtid.h>
#endif

#include <pxr/base/tf/refPtr.h>

PXR_NAMESPACE_OPEN_SCOPE

typedef Ufe::Path (*MayaHydraInterpretRprimPath)(const HdSceneIndexBaseRefPtr&, const SdfPath&);

TF_REGISTRY_FUNCTION(TfType)
{
HdSceneIndexPluginRegistry::
Expand All @@ -56,19 +62,45 @@ HdSceneIndexBaseRefPtr MayaUsdProxyShapeMayaNodeSceneIndexPlugin::_AppendSceneIn
using HdMObjectDataSource = HdRetainedTypedSampledDataSource<MObject>;
static TfToken dataSourceNodePathEntry("object");
HdDataSourceBaseHandle dataSourceEntryPathHandle = inputArgs->Get(dataSourceNodePathEntry);
#if WANT_UFE_BUILD
using HdRtidRefDataSource = HdRetainedTypedSampledDataSource<Ufe::Rtid&>;
static TfToken dataSourceRuntimeEntry("runtime");
HdDataSourceBaseHandle dataSourceEntryRuntimeHandle = inputArgs->Get(dataSourceRuntimeEntry);
#endif

// Retrieve the version integer. The Version integer combines major, minor, and patch number
// like this major * 10000 + minor * 100 + patch
using MayaHydraVersionDataSource = HdRetainedTypedSampledDataSource<int>;
static TfToken dataSourceVersionEntry("version");
HdDataSourceBaseHandle dataSourceEntryVersionHandle = inputArgs->Get(dataSourceVersionEntry);
int version = 100; // initial mayaHydra version where version data source had not been defined
ppt-adsk marked this conversation as resolved.
Show resolved Hide resolved
if (auto dataSourceEntryVersion
= MayaHydraVersionDataSource::Cast(dataSourceEntryVersionHandle)) {
version = dataSourceEntryVersion->GetTypedValue(0.0f);
}

if (auto dataSourceEntryNodePath = HdMObjectDataSource::Cast(dataSourceEntryPathHandle)) {
#if WANT_UFE_BUILD
auto dataSourceEntryRuntime = HdRtidRefDataSource::Cast(dataSourceEntryRuntimeHandle);
if (TF_VERIFY(dataSourceEntryRuntime, "Error UFE runtime id data source not found")) {
Ufe::Rtid& id = dataSourceEntryRuntime->GetTypedValue(0.0f);
id = MayaUsd::ufe::getUsdRunTimeId();
TF_VERIFY(id != 0, "Invalid UFE runtime id");
if (version >= 200) {
// Retrieve interpret pick function from the scene index plugin, to be accessed by
// mayaHydra interpretRprimPath
using MayaHydraInterpretRprimPathDataSource
= HdRetainedTypedSampledDataSource<MayaHydraInterpretRprimPath&>;
static TfToken dataSourceInterpretPickEntry("interpretRprimPath");
HdDataSourceBaseHandle dataSourceEntryInterpretPickHandle
= inputArgs->Get(dataSourceInterpretPickEntry);
auto dataSourceEntryInterpretPick
= MayaHydraInterpretRprimPathDataSource::Cast(dataSourceEntryInterpretPickHandle);
MayaHydraInterpretRprimPath& interpretRprimPath
= dataSourceEntryInterpretPick->GetTypedValue(0.0f);
interpretRprimPath = (MayaHydraInterpretRprimPath)&MayaUsd::
MayaUsdProxyShapeSceneIndex::InterpretRprimPath;
} else {
using HdRtidRefDataSource = HdRetainedTypedSampledDataSource<Ufe::Rtid&>;
static TfToken dataSourceRuntimeEntry("runtime");
HdDataSourceBaseHandle dataSourceEntryRuntimeHandle
= inputArgs->Get(dataSourceRuntimeEntry);
auto dataSourceEntryRuntime = HdRtidRefDataSource::Cast(dataSourceEntryRuntimeHandle);
if (TF_VERIFY(dataSourceEntryRuntime, "Error UFE runtime id data source not found")) {
Ufe::Rtid& id = dataSourceEntryRuntime->GetTypedValue(0.0f);
id = MayaUsd::ufe::getUsdRunTimeId();
TF_VERIFY(id != 0, "Invalid UFE runtime id");
}
}
ppt-adsk marked this conversation as resolved.
Show resolved Hide resolved
#endif
MObject dagNode = dataSourceEntryNodePath->GetTypedValue(0.0f);
Expand All @@ -80,10 +112,13 @@ HdSceneIndexBaseRefPtr MayaUsdProxyShapeMayaNodeSceneIndexPlugin::_AppendSceneIn

auto proxyShape = dynamic_cast<MayaUsdProxyShapeBase*>(dependNodeFn.userNode());
if (TF_VERIFY(proxyShape, "Error getting MayaUsdProxyShapeBase")) {
auto psSceneIndex = MayaUsd::MayaUsdProxyShapeSceneIndex::New(proxyShape);
// Convert USD prims to rprims consumed by Hydra
auto usdImagingStageSceneIndex = UsdImagingStageSceneIndex::New();
// Flatten transforms, visibility, purpose, model, and material
// bindings over hierarchies.
return HdFlatteningSceneIndex::New(psSceneIndex);
auto flatteningSceneIndex = HdFlatteningSceneIndex::New(usdImagingStageSceneIndex);
return MayaUsd::MayaUsdProxyShapeSceneIndex::New(
proxyShape, flatteningSceneIndex, usdImagingStageSceneIndex);
}
}

Expand All @@ -97,10 +132,11 @@ namespace MAYAUSD_NS_DEF {
///////////////////////// MayaUsdProxyShapeSceneIndex

MayaUsdProxyShapeSceneIndex::MayaUsdProxyShapeSceneIndex(
UsdImagingStageSceneIndexRefPtr inputSceneIndex,
HdSceneIndexBaseRefPtr inputSceneIndex,
UsdImagingStageSceneIndexRefPtr usdImagingStageSceneIndex,
MayaUsdProxyShapeBase* proxyShape)
: ParentClass(inputSceneIndex)
, _usdImagingStageSceneIndex(inputSceneIndex)
, _usdImagingStageSceneIndex(usdImagingStageSceneIndex)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, this is passed in as a argument to support a temporary workaround, and init on first use of _usdImagingStageSceneIndex. However, why is it the responsibility of the MayaUsdProxyShapeSceneIndex to set the stage in Populate() of something that is arguably external to it? Can't we set the stage onto the _usdImagingStageSceneIndex upon its construction? A proxy shape node's stage won't change.

Copy link
Contributor Author

@perrauo-adsk perrauo-adsk Apr 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the MayaUsdProxyShapeSceneIndex also listens for changes:

void MayaUsdProxyShapeSceneIndex::ObjectsChanged(
    const MayaUsdProxyStageObjectsChangedNotice& notice)
{
    _usdImagingStageSceneIndex->ApplyPendingUpdates();
}

Copy link
Contributor Author

@perrauo-adsk perrauo-adsk Apr 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please note, that changing the inner working of MayaUsdProxySHapeSceneIndex is out of scope for these changes. The intent is simply to change data source involve, and implementing the interpretDataSource. Changing the ::New is already a bit of a stretch and came as a result of needing to expose the proxyshapesceneindex as top level scene index.

, _proxyShape(proxyShape)
{
TfWeakPtr<MayaUsdProxyShapeSceneIndex> ptr(this);
Expand All @@ -110,6 +146,32 @@ MayaUsdProxyShapeSceneIndex::MayaUsdProxyShapeSceneIndex(

MayaUsdProxyShapeSceneIndex::~MayaUsdProxyShapeSceneIndex() { }

MayaUsdProxyShapeSceneIndexRefPtr MayaUsdProxyShapeSceneIndex::New(
MayaUsdProxyShapeBase* proxyShape,
const HdFlatteningSceneIndexRefPtr& flatteningSceneIndex,
const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex)
{
// Create the proxy shape scene index which populates the stage
return TfCreateRefPtr(new MayaUsdProxyShapeSceneIndex(
flatteningSceneIndex, usdImagingStageSceneIndex, proxyShape));
}

Ufe::Path MayaUsdProxyShapeSceneIndex::InterpretRprimPath(
const HdSceneIndexBaseRefPtr& sceneIndex,
const SdfPath& path)
{
if (MayaUsdProxyShapeSceneIndexRefPtr proxyShapeSceneIndex
= TfStatic_cast<MayaUsdProxyShapeSceneIndexRefPtr>(sceneIndex)) {
MStatus status;
MDagPath dagPath(
MDagPath::getAPathTo(proxyShapeSceneIndex->_proxyShape->thisMObject(), &status));
return Ufe::Path({ MayaUsd::ufe::dagPathToPathSegment(dagPath),
MayaUsd::ufe::usdPathToUfePathSegment(path) });
}

return Ufe::Path();
}

void MayaUsdProxyShapeSceneIndex::StageSet(const MayaUsdProxyStageSetNotice& notice) { Populate(); }

void MayaUsdProxyShapeSceneIndex::ObjectsChanged(
Expand All @@ -134,6 +196,8 @@ void MayaUsdProxyShapeSceneIndex::Populate()
{
_usdImagingStageSceneIndex->SetStage(stage);
#if PXR_VERSION <= 2305
// In most recent USD, Populate is called from within SetStage, so there is no need
// to callsites to call it explicitly
_usdImagingStageSceneIndex->Populate();
#endif
_populated = true;
Expand All @@ -156,7 +220,7 @@ HdSceneIndexPrim MayaUsdProxyShapeSceneIndex::GetPrim(const SdfPath& primPath) c
return HdSceneIndexPrim();
}

return _usdImagingStageSceneIndex->GetPrim(primPath);
return _GetInputSceneIndex()->GetPrim(primPath);
}

SdfPathVector MayaUsdProxyShapeSceneIndex::GetChildPrimPaths(const SdfPath& primPath) const
Expand Down
22 changes: 16 additions & 6 deletions lib/mayaUsd/sceneIndex/proxyShapeSceneIndexPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,19 @@
#include <pxr/usd/sdf/path.h>
#include <pxr/usdImaging/usdImaging/stageSceneIndex.h>

#if WANT_UFE_BUILD
#include <ufe/path.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be forward declared.

#endif

#include <memory>

//////////////////////////////////////////////////////////////// MayaUsdProxyShapeSceneIndexPlugin

PXR_NAMESPACE_OPEN_SCOPE

class HdFlatteningSceneIndex;
TF_DECLARE_WEAK_AND_REF_PTRS(HdFlatteningSceneIndex);

// The plugin class must be present in the pixar scope otherwise the factory method registered by
// HdSceneIndexPluginRegistry::Define will not be available from the string constructed from the
// node type name.
Expand Down Expand Up @@ -70,19 +77,22 @@ class MayaUsdProxyShapeSceneIndex : public HdSingleInputFilteringSceneIndexBase
public:
using ParentClass = HdSingleInputFilteringSceneIndexBase;

static MayaUsdProxyShapeSceneIndexRefPtr New(MayaUsdProxyShapeBase* proxyShape)
{
return TfCreateRefPtr(
new MayaUsdProxyShapeSceneIndex(UsdImagingStageSceneIndex::New(), proxyShape));
}
static MayaUsdProxyShapeSceneIndexRefPtr
New(MayaUsdProxyShapeBase* proxyShape,
const HdFlatteningSceneIndexRefPtr& flatteningSceneIndex,
const UsdImagingStageSceneIndexRefPtr& usdImagingStageSceneIndex);

static Ufe::Path
InterpretRprimPath(const HdSceneIndexBaseRefPtr& sceneIndex, const SdfPath& path);

// satisfying HdSceneIndexBase
HdSceneIndexPrim GetPrim(const SdfPath& primPath) const override;

SdfPathVector GetChildPrimPaths(const SdfPath& primPath) const override;

MayaUsdProxyShapeSceneIndex(
UsdImagingStageSceneIndexRefPtr inputSceneIndex,
HdSceneIndexBaseRefPtr inputSceneIndex,
UsdImagingStageSceneIndexRefPtr usdImagingStageSceneIndex,
MayaUsdProxyShapeBase* proxyShape);

virtual ~MayaUsdProxyShapeSceneIndex();
Expand Down