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

Implemented Outliner orphaned nodes, pulled node tooltips and italics. #2285

Merged
merged 5 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/mayaUsd/resources/icons/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ set(LIB_ICONS
edit_as_Maya
merge_to_USD
cache_to_USD
orphaned_node_badge
)
foreach(ICON_BASE ${LIB_ICONS})
# The _100.png files need to be installed without the _100. This is the
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions lib/mayaUsd/ufe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ endif()
if(CMAKE_UFE_V3_FEATURES_AVAILABLE)
target_sources(${PROJECT_NAME}
PRIVATE
# See MayaUIInfoHandler.h comments.
MayaUIInfoHandler.cpp
PulledObjectHierarchy.cpp
PulledObjectHierarchyHandler.cpp
UsdPathMappingHandler.cpp
Expand Down Expand Up @@ -157,6 +159,9 @@ endif()

if(CMAKE_UFE_V3_FEATURES_AVAILABLE)
list(APPEND HEADERS
# Not dependent on UFE v3, but used to draw orphaned pulled Maya nodes
# in the Outliner, which is a UFE v3 feature.
MayaUIInfoHandler.h
PulledObjectHierarchy.h
PulledObjectHierarchyHandler.h
UsdPathMappingHandler.h
Expand Down
43 changes: 29 additions & 14 deletions lib/mayaUsd/ufe/Global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#endif
#ifdef UFE_V3_FEATURES_AVAILABLE
#define HAVE_PATH_MAPPING
#include <mayaUsd/ufe/MayaUIInfoHandler.h>
#include <mayaUsd/ufe/PulledObjectHierarchyHandler.h>
#include <mayaUsd/ufe/UsdPathMappingHandler.h>
#endif
Expand Down Expand Up @@ -105,6 +106,8 @@ Ufe::ContextOpsHandler::Ptr g_MayaContextOpsHandler;

#ifdef HAVE_PATH_MAPPING
Ufe::PathMappingHandler::Ptr g_MayaPathMappingHandler;

Ufe::UIInfoHandler::Ptr g_MayaUIInfoHandler;
#endif

// Subject singleton for observation of all USD stages.
Expand All @@ -126,26 +129,27 @@ MStatus initialize()
return MS::kSuccess;

// Replace the Maya hierarchy handler with ours.
g_MayaRtid = Ufe::RunTimeMgr::instance().getId(kMayaRunTimeName);
auto& runTimeMgr = Ufe::RunTimeMgr::instance();
g_MayaRtid = runTimeMgr.getId(kMayaRunTimeName);
#if !defined(NDEBUG)
assert(g_MayaRtid != 0);
#endif
if (g_MayaRtid == 0)
return MS::kFailure;

g_MayaHierarchyHandler = Ufe::RunTimeMgr::instance().hierarchyHandler(g_MayaRtid);
g_MayaHierarchyHandler = runTimeMgr.hierarchyHandler(g_MayaRtid);
auto proxyShapeHierHandler = ProxyShapeHierarchyHandler::create(g_MayaHierarchyHandler);
#ifdef UFE_V3_FEATURES_AVAILABLE
auto pulledObjectHierHandler = PulledObjectHierarchyHandler::create(proxyShapeHierHandler);
Ufe::RunTimeMgr::instance().setHierarchyHandler(g_MayaRtid, pulledObjectHierHandler);
runTimeMgr.setHierarchyHandler(g_MayaRtid, pulledObjectHierHandler);
#else
Ufe::RunTimeMgr::instance().setHierarchyHandler(g_MayaRtid, proxyShapeHierHandler);
runTimeMgr.setHierarchyHandler(g_MayaRtid, proxyShapeHierHandler);
#endif

#ifdef UFE_V2_FEATURES_AVAILABLE
g_MayaContextOpsHandler = Ufe::RunTimeMgr::instance().contextOpsHandler(g_MayaRtid);
g_MayaContextOpsHandler = runTimeMgr.contextOpsHandler(g_MayaRtid);
auto proxyShapeContextOpsHandler = ProxyShapeContextOpsHandler::create(g_MayaContextOpsHandler);
Ufe::RunTimeMgr::instance().setContextOpsHandler(g_MayaRtid, proxyShapeContextOpsHandler);
runTimeMgr.setContextOpsHandler(g_MayaRtid, proxyShapeContextOpsHandler);
#endif

#ifdef UFE_V2_FEATURES_AVAILABLE
Expand Down Expand Up @@ -188,20 +192,25 @@ MStatus initialize()

handlers.transform3dHandler = pointInstanceHandler;

g_USDRtid = Ufe::RunTimeMgr::instance().register_(kUSDRunTimeName, handlers);
g_USDRtid = runTimeMgr.register_(kUSDRunTimeName, handlers);
MayaUsd::ufe::UsdUIUfeObserver::create();

#ifdef HAVE_PATH_MAPPING
g_MayaPathMappingHandler = Ufe::RunTimeMgr::instance().pathMappingHandler(g_MayaRtid);
g_MayaPathMappingHandler = runTimeMgr.pathMappingHandler(g_MayaRtid);
auto pathMappingHndlr = UsdPathMappingHandler::create();
Ufe::RunTimeMgr::instance().setPathMappingHandler(g_MayaRtid, pathMappingHndlr);
runTimeMgr.setPathMappingHandler(g_MayaRtid, pathMappingHndlr);

// Replace any existing info handler with our own.
g_MayaUIInfoHandler = runTimeMgr.uiInfoHandler(g_MayaRtid);
auto uiInfoHandler = MayaUIInfoHandler::create();
runTimeMgr.setUIInfoHandler(g_MayaRtid, uiInfoHandler);
#endif

#else
auto usdHierHandler = UsdHierarchyHandler::create();
auto usdTrans3dHandler = UsdTransform3dHandler::create();
auto usdSceneItemOpsHandler = UsdSceneItemOpsHandler::create();
g_USDRtid = Ufe::RunTimeMgr::instance().register_(
g_USDRtid = runTimeMgr.register_(
kUSDRunTimeName, usdHierHandler, usdTrans3dHandler, usdSceneItemOpsHandler);
#endif

Expand Down Expand Up @@ -229,27 +238,33 @@ MStatus initialize()

MStatus finalize(bool exiting)
{
auto& runTimeMgr = Ufe::RunTimeMgr::instance();

// If more than one plugin still has us registered, do nothing.
if (gRegistrationCount-- > 1 && !exiting)
return MS::kSuccess;

// Restore the normal Maya hierarchy handler, and unregister.
Ufe::RunTimeMgr::instance().setHierarchyHandler(g_MayaRtid, g_MayaHierarchyHandler);
runTimeMgr.setHierarchyHandler(g_MayaRtid, g_MayaHierarchyHandler);
#ifdef UFE_V2_FEATURES_AVAILABLE
// Restore the normal Maya context ops handler (can be empty).
if (g_MayaContextOpsHandler)
Ufe::RunTimeMgr::instance().setContextOpsHandler(g_MayaRtid, g_MayaContextOpsHandler);
runTimeMgr.setContextOpsHandler(g_MayaRtid, g_MayaContextOpsHandler);
g_MayaContextOpsHandler.reset();

MayaUsd::ufe::UsdUIUfeObserver::destroy();
#endif
Ufe::RunTimeMgr::instance().unregister(g_USDRtid);
runTimeMgr.unregister(g_USDRtid);
g_MayaHierarchyHandler.reset();

#ifdef HAVE_PATH_MAPPING
// Remove the Maya path mapping handler that we added above.
Ufe::RunTimeMgr::instance().setPathMappingHandler(g_MayaRtid, g_MayaPathMappingHandler);
runTimeMgr.setPathMappingHandler(g_MayaRtid, g_MayaPathMappingHandler);
g_MayaPathMappingHandler.reset();

// Remove the Maya path mapping handler that we added above.
runTimeMgr.setUIInfoHandler(g_MayaRtid, g_MayaUIInfoHandler);
g_MayaUIInfoHandler.reset();
#endif

g_StagesSubject.Reset();
Expand Down
150 changes: 150 additions & 0 deletions lib/mayaUsd/ufe/MayaUIInfoHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Core file in the review.

// Copyright 2022 Autodesk
//
// 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.
//
#include "MayaUIInfoHandler.h"

#include <mayaUsd/fileio/primUpdaterManager.h>
#include <mayaUsd/ufe/Global.h>
#include <mayaUsd/ufe/UsdSceneItem.h>
#include <mayaUsd/utils/util.h>

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

#include <ufe/hierarchy.h>
#include <ufe/pathString.h>

// Needed for Tf diagnostic macros.
PXR_NAMESPACE_USING_DIRECTIVE

namespace {

// Find a pulled Maya node's USD pulled ancestor by iterating up the Maya
// path. Iteration stops when a Maya node with pull information has been
// found, which can be for the initial path itself, when the Maya node is
// the root of the pulled sub-hierarchy.
//
// Note that if it exists, the USD pulled ancestor prim is inactive, which is
// done to avoid having that prim and its sub-hierarchy exist in the scene as
// stale USD duplicates of Maya pulled nodes. If the USD pulled ancestor does
// not exist, the argument Maya node is orphaned.
MayaUsd::ufe::UsdSceneItem::Ptr pulledUsdAncestorItem(const Ufe::SceneItem::Ptr& mayaItem)
{
// This function requires a Maya item to compute its USD ancestor.
if (!TF_VERIFY(mayaItem->runTimeId() == MayaUsd::ufe::getMayaRunTimeId())) {
return nullptr;
}

// Find the pulled ancestor by iterating up the Maya path.
auto mayaPath = mayaItem->path();
bool found { false };
Ufe::Path usdItemPath;
while (!found) {
// A pulled node either has the pull information itself, or has a
// pulled ancestor that does.
if (!TF_VERIFY(!mayaPath.empty())) {
return nullptr;
}
const auto mayaPathStr = Ufe::PathString::string(mayaPath);
const auto dagPath = UsdMayaUtil::nameToDagPath(mayaPathStr);
if (PrimUpdaterManager::readPullInformation(dagPath, usdItemPath)) {
found = true;
} else {
mayaPath = mayaPath.pop();
}
}

// Try to create a USD scene item (and its underlying prim) from the pulled
// ancestor USD path. If no such USD prim exists, our argument Maya node
// is orphaned.
return std::static_pointer_cast<MayaUsd::ufe::UsdSceneItem>(
Ufe::Hierarchy::createItem(usdItemPath));
}

// A Maya node is orphaned if its pulled ancestor is not in the scene.
bool isOrphaned(const Ufe::SceneItem::Ptr& mayaItem)
{
return pulledUsdAncestorItem(mayaItem) == nullptr;
}

} // namespace

namespace MAYAUSD_NS_DEF {
namespace ufe {

MayaUIInfoHandler::MayaUIInfoHandler()
: Ufe::UIInfoHandler()
{
}

MayaUIInfoHandler::~MayaUIInfoHandler() { }

/*static*/
MayaUIInfoHandler::Ptr MayaUIInfoHandler::create() { return std::make_shared<MayaUIInfoHandler>(); }

//------------------------------------------------------------------------------
// Ufe::UIInfoHandler overrides
//------------------------------------------------------------------------------

bool MayaUIInfoHandler::treeViewCellInfo(const Ufe::SceneItem::Ptr& mayaItem, Ufe::CellInfo& info)
const
{
if (isOrphaned(mayaItem)) {
// If the Maya node is orphaned, dim it to 60%.
const float d { 0.6f };
auto& c = info.textFgColor;
c.set(c.r() * d, c.g() * d, c.b() * d);
return true;
}

// If the argument Maya scene item corresponds to the root of the pulled
// hierarchy, set its font to italics.
auto dagPath = UsdMayaUtil::nameToDagPath(Ufe::PathString::string(mayaItem->path()));
Ufe::Path usdItemPath;
if (PrimUpdaterManager::readPullInformation(dagPath, usdItemPath)) {
info.fontItalics = true;
return true;
}
return false;
}

Ufe::UIInfoHandler::Icon MayaUIInfoHandler::treeViewIcon(const Ufe::SceneItem::Ptr& mayaItem) const
{
return isOrphaned(mayaItem)
? Ufe::UIInfoHandler::Icon("", "orphaned_node_badge", Ufe::UIInfoHandler::LowerRight)
: Ufe::UIInfoHandler::Icon();
}

std::string MayaUIInfoHandler::treeViewTooltip(const Ufe::SceneItem::Ptr& mayaItem) const
{
// If the pulled USD ancestor does not exist, the Maya node is orphaned.
auto usdItem = pulledUsdAncestorItem(mayaItem);
if (!usdItem) {
return {};
}

// Show the stage of the pulled item, and that pulled nodes are locked.
// Stage name is the last node of the first segment.
auto stageName = Ufe::Path(usdItem->path().getSegments()[0]).back().string();
std::string toolTip { "<b>Stage:</b> " };
toolTip += stageName;
toolTip += "<br>Locked Node";

return toolTip;
}

std::string MayaUIInfoHandler::getLongRunTimeLabel() const { return "Maya"; }

} // namespace ufe
} // namespace MAYAUSD_NS_DEF
55 changes: 55 additions & 0 deletions lib/mayaUsd/ufe/MayaUIInfoHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef MAYAUIINFOHANDLER_H
#define MAYAUIINFOHANDLER_H

//
// Copyright 2022 Autodesk
//
// 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.
//

#include <mayaUsd/base/api.h>

#include <ufe/uiInfoHandler.h>

namespace MAYAUSD_NS_DEF {
namespace ufe {

//! \brief Implementation of Ufe::UIInfoHandler interface for Maya objects.
class MAYAUSD_CORE_PUBLIC MayaUIInfoHandler : public Ufe::UIInfoHandler
{
public:
typedef std::shared_ptr<MayaUIInfoHandler> Ptr;

MayaUIInfoHandler();
~MayaUIInfoHandler() override;

// Delete the copy/move constructors assignment operators.
MayaUIInfoHandler(const MayaUIInfoHandler&) = delete;
MayaUIInfoHandler& operator=(const MayaUIInfoHandler&) = delete;
MayaUIInfoHandler(MayaUIInfoHandler&&) = delete;
MayaUIInfoHandler& operator=(MayaUIInfoHandler&&) = delete;

//! Create a MayaUIInfoHandler.
static MayaUIInfoHandler::Ptr create();

// Ufe::UIInfoHandler overrides
bool treeViewCellInfo(const Ufe::SceneItem::Ptr& item, Ufe::CellInfo& info) const override;
Ufe::UIInfoHandler::Icon treeViewIcon(const Ufe::SceneItem::Ptr& item) const override;
std::string treeViewTooltip(const Ufe::SceneItem::Ptr& item) const override;
std::string getLongRunTimeLabel() const override;
}; // MayaUIInfoHandler

} // namespace ufe
} // namespace MAYAUSD_NS_DEF

#endif // MAYAUIINFOHANDLER_H
2 changes: 1 addition & 1 deletion lib/mayaUsd/ufe/UsdUIInfoHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
namespace MAYAUSD_NS_DEF {
namespace ufe {

//! \brief Interface to create a UsdUIInfoHandler interface object.
//! \brief Implementation of Ufe::UIInfoHandler interface for USD objects.
class MAYAUSD_CORE_PUBLIC UsdUIInfoHandler : public Ufe::UIInfoHandler
{
public:
Expand Down