Skip to content

Commit

Permalink
Replace DataProducersNodeHashCodeToSdfPathRegistry with path mapping. (
Browse files Browse the repository at this point in the history
  • Loading branch information
ppt-adsk authored Feb 11, 2025
1 parent e336a59 commit f7dffda
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 42 deletions.
5 changes: 5 additions & 0 deletions lib/flowViewport/selection/fvpPathMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class PathMapper
FVP_API
virtual PrimSelections UfePathToPrimSelections(const Ufe::Path& appPath) const = 0;

//! Return the path mapper's name. Intended for debugging.
//! \return Path mapper name.
FVP_API
virtual std::string Name() const = 0;

protected:

FVP_API
Expand Down
2 changes: 1 addition & 1 deletion lib/flowViewport/selection/fvpPathMapperRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ PathMapperConstPtr PathMapperRegistry::GetMapper(const Ufe::Path& path) const

PrimSelections PathMapperRegistry::UfePathToPrimSelections(
const Ufe::Path& appPath
)
) const
{
if (appPath.empty()) {
return {};
Expand Down
2 changes: 1 addition & 1 deletion lib/flowViewport/selection/fvpPathMapperRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class PathMapperRegistry {
PathMapperConstPtr GetFallbackMapper() const;

FVP_API
PrimSelections UfePathToPrimSelections(const Ufe::Path& appPath);
PrimSelections UfePathToPrimSelections(const Ufe::Path& appPath) const;

//! Testing interface
FVP_API
Expand Down
30 changes: 18 additions & 12 deletions lib/flowViewport/selection/fvpPrefixPathMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,50 @@
#include <flowViewport/selection/fvpPrefixPathMapper.h>
#include <flowViewport/fvpUtils.h>

#include <ufe/pathString.h>

// Need Pixar namespace for TF_ diagnostics macros.
PXR_NAMESPACE_USING_DIRECTIVE

namespace FVP_NS_DEF {

PrefixPathMapper::PrefixPathMapper(
Ufe::Rtid rtid,
const Ufe::Path& appPathPrefix,
const PXR_NS::SdfPath& sceneIndexPathPrefix
) : _rtid(rtid), _appPathPrefix(appPathPrefix),
) : _appPathPrefix(appPathPrefix),
_sceneIndexPathPrefix(sceneIndexPathPrefix)
{}

PrimSelections PrefixPathMapper::UfePathToPrimSelections(const Ufe::Path& appPath) const
{
// We only handle scene items from our assigned run time ID.
if (appPath.runTimeId() != _rtid) {
return {};
}

// If the data model object application path does not match the path we
// translate, return an empty path.
if (!appPath.startsWith(_appPathPrefix)) {
return {};
}

// The scene index path is composed of 2 parts, in order:
// The scene index path is composed of 2 parts, the second of which is
// optional:
// 1) The scene index path prefix, which is fixed on construction.
// 2) The second segment of the UFE path, with each UFE path component
// becoming an SdfPath component.
PXR_NS::SdfPath primPath = _sceneIndexPathPrefix;
TF_AXIOM(appPath.nbSegments() == 2);
const auto& secondSegment = appPath.getSegments()[1];
for (const auto& pathComponent : secondSegment) {
primPath = primPath.AppendChild(TfToken(pathComponent.string()));
if (appPath.nbSegments() == 2) {
const auto& secondSegment = appPath.getSegments()[1];
for (const auto& pathComponent : secondSegment) {
primPath = primPath.AppendChild(TfToken(pathComponent.string()));
}
}

return PrimSelections{PrimSelection{primPath}};
}

std::string PrefixPathMapper::Name() const
{
std::ostringstream oss;
oss << "PrefixPathMapper " << Ufe::PathString::string(_appPathPrefix)
<< " --> " << _sceneIndexPathPrefix.GetText() << std::endl;
return oss.str();
}

}
10 changes: 4 additions & 6 deletions lib/flowViewport/selection/fvpPrefixPathMapper.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024 Autodesk
// Copyright 2025 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -19,7 +19,6 @@
#include <flowViewport/api.h>
#include <flowViewport/selection/fvpPathMapper.h>

#include <ufe/rtid.h>
#include <ufe/path.h>

namespace FVP_NS_DEF {
Expand All @@ -28,8 +27,6 @@ namespace FVP_NS_DEF {
///
/// This simple path handler performs application path to scene index path
/// mapping by substituting a scene index prefix for an application path prefix.
/// The prefix mapper applies only to application paths of a specific UFE run
/// time.
///

class PrefixPathMapper : public PathMapper
Expand All @@ -38,17 +35,18 @@ class PrefixPathMapper : public PathMapper

FVP_API
PrefixPathMapper(
Ufe::Rtid rtid,
const Ufe::Path& appPathPrefix,
const PXR_NS::SdfPath& sceneIndexPathPrefix
);

FVP_API
PrimSelections UfePathToPrimSelections(const Ufe::Path& appPath) const override;

FVP_API
virtual std::string Name() const;

private:

const Ufe::Rtid _rtid{0}; // 0 is invalid
const Ufe::Path _appPathPrefix;
const PXR_NS::SdfPath _sceneIndexPathPrefix;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ void MhFlowViewportAPILocator::addedToModelCb()
// for selection highlighting.
_appPath = getUfePath();
auto pathMapper = std::make_shared<Fvp::PrefixPathMapper>(
ufeRunTimeId, _appPath, _pathPrefix);
_appPath, _pathPrefix);
TF_AXIOM(Fvp::PathMapperRegistry::Instance().Register(_appPath, pathMapper));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
//Flow viewport headers
#include <flowViewport/API/fvpVersionInterface.h>
#include <flowViewport/API/fvpDataProducerSceneIndexInterface.h>
#include <flowViewport/selection/fvpPrefixPathMapper.h>
#include <flowViewport/selection/fvpPathMapperRegistry.h>

//Hydra headers
#include <pxr/base/vt/array.h>
Expand Down Expand Up @@ -138,6 +140,8 @@ class MhFootPrint : public MPxLocatorNode
// Callback when the footprint node is removed from model (delete)
void removedFromModelCb();

Ufe::Path getUfePath() const;

//Attributes
static MObject mSize;
static MObject mWorldS;
Expand Down Expand Up @@ -176,6 +180,7 @@ class MhFootPrint : public MPxLocatorNode
MCallbackId _nodeRemovedFromModelCbId{0};

SdfPath _pathPrefix;
Ufe::Path _appPath{};
};

namespace
Expand Down Expand Up @@ -596,6 +601,13 @@ void* MhFootPrint::creator()
return new MhFootPrint();
}

Ufe::Path MhFootPrint::getUfePath() const
{
MDagPath dagPath;
TF_AXIOM(MDagPath::getAPathTo(thisMObject(), dagPath) == MS::kSuccess);
return Ufe::Path(UfeExtensions::dagPathToUfePathSegment(dagPath));
}

void MhFootPrint::addedToModelCb()
{
_pathPrefix = SdfPath(TfStringPrintf("/MhFootPrint_%p", this));
Expand All @@ -612,13 +624,20 @@ void MhFootPrint::addedToModelCb()
auto pickHandler = std::make_shared<FootPrintPickHandler>(obj);
TF_AXIOM(MayaHydra::PickHandlerRegistry::Instance().Register(_pathPrefix, pickHandler));

// No need for a path mapper: the parts of the footprint are not selectable
// individually, only the Maya shape, so the built-in Maya path mapper does
// the job of path mapping for the footprint node.
// Register a path mapper to map application UFE paths to scene index paths,
// for selection highlighting.
_appPath = getUfePath();
auto pathMapper = std::make_shared<Fvp::PrefixPathMapper>(_appPath, _pathPrefix);
TF_AXIOM(Fvp::PathMapperRegistry::Instance().Register(_appPath, pathMapper));
}

void MhFootPrint::removedFromModelCb()
{
// Unregister our path mapper. Use stored UFE path, as at this point
// our locator node is no longer in the Maya scene, so we cannot obtain
// an MDagPath for it.
TF_AXIOM(Fvp::PathMapperRegistry::Instance().Unregister(_appPath));

// Unregister our pick handler.
TF_AXIOM(MayaHydra::PickHandlerRegistry::Instance().Unregister(_pathPrefix));

Expand Down
21 changes: 9 additions & 12 deletions lib/mayaHydra/hydraExtensions/sceneIndex/mayaHydraSceneIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ class MayaPathMapper : public Fvp::PathMapper
return _piSi.UfePathToPrimSelections(appPath);
}

std::string Name() const { return "MayaPathMapper"; }

private:
// Non-owning reference to prevent ownership cycle.
const MayaHydraSceneIndex& _piSi;
Expand Down Expand Up @@ -788,20 +790,15 @@ Fvp::PrimSelections MayaHydraSceneIndex::UfePathToPrimSelections(const Ufe::Path
MDagPath shapeDagPath(dagPath);
shapeDagPath.extendToShape();

// Check if this Maya node has a special path mapper associated with it.
Ufe::Path shapeAppPath{UfeExtensions::dagPathToUfePathSegment(shapeDagPath)};
const auto& pmr = Fvp::PathMapperRegistry::Instance();
if (pmr.HasMapper(shapeAppPath)) {
return pmr.UfePathToPrimSelections(shapeAppPath);
}

SdfPath primPath = GetPrimPath((extendToShape) ? shapeDagPath : dagPath, isSprim);

//Check if this maya node has a special SdfPath associated with it, this is for custom or maya usd data producers scene indices.
//The class MhDataProducersMayaNodeToSdfPathRegistry does a mapping between Maya nodes and USD paths.
//The maya nodes registered in this class are used by data producers as a parent to all
//primitives. This class is used when the user selects one of these
//maya nodes to return the matching SdfPath so that all prims child of this maya node are
//highlighted.

const SdfPath matchingPath = FVP_NS::DataProducersNodeHashCodeToSdfPathRegistry::Instance().GetPath(MObjectHandle(shapeDagPath.node()).hashCode());
if (! matchingPath.IsEmpty()) {
primPath = matchingPath;
}

TF_DEBUG(MAYAHYDRALIB_SCENE_INDEX)
.Msg(" mapped to scene index path %s.\n", primPath.GetText());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class UsdPathMapper : public Fvp::PathMapper
return _psSi.UfePathToPrimSelections(appPath);
}

std::string Name() const override { return "UsdPathMapper"; }

private:
// Non-owning reference to prevent ownership cycle.
const MayaUsdProxyShapeSceneIndex& _psSi;
Expand Down Expand Up @@ -331,18 +333,19 @@ Fvp::PrimSelections MayaUsdProxyShapeSceneIndex::UfePathToPrimSelections(
const Ufe::Path& appPath
) const
{
// We only handle USD objects, so if the UFE path is not a USD object,
// early out with failure.
if (appPath.runTimeId() != UfeExtensions::getUsdRunTimeId()) {
return {};
}

// If the data model object application path does not match the path we
// translate, return an empty path.
if (!appPath.startsWith(_sceneIndexAppPath)) {
return {};
}

// If the application path is our prefix, just return the
// corresponding scene index path.
if (appPath == _sceneIndexAppPath) {
return Fvp::PrimSelections{Fvp::PrimSelection{
_sceneIndexPathPrefix}};
}

// The scene index path is composed of 2 parts, in order:
// 1) The scene index path prefix, which is fixed on construction.
// 2) The second segment of the UFE path, with each UFE path component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class TestPathMapper : public Fvp::PathMapper {

Fvp::PrimSelections
UfePathToPrimSelections(const Ufe::Path&) const override { return {}; }

std::string Name() const { return "TestPathMapper"; }
};

}
Expand Down

0 comments on commit f7dffda

Please sign in to comment.