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

Restrict UFE nodes according to proxyNode's primPath #3640

Merged
merged 6 commits into from
Mar 14, 2024
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
45 changes: 34 additions & 11 deletions lib/mayaUsd/nodes/proxyShapeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1287,16 +1287,16 @@ MStatus MayaUsdProxyShapeBase::computeOutStageData(MDataBlock& dataBlock)
}

// Get the primPath
const MString primPath = dataBlock.inputValue(primPathAttr, &retValue).asString();
CHECK_MSTATUS_AND_RETURN_IT(retValue);
const SdfPath primPath = _GetPrimPath(dataBlock);
if (primPath.IsEmpty()) {
return MS::kFailure;
}

// Get the prim
// If no primPath string specified, then use the pseudo-root.
UsdPrim usdPrim;
std::string primPathStr(primPath.asChar(), primPath.length());
if (!primPathStr.empty()) {
SdfPath primPath(primPathStr);

UsdPrim usdPrim;
if (primPath == SdfPath::AbsoluteRootPath()) {
usdPrim = usdStage->GetPseudoRoot();
} else {
// Validate assumption: primPath is descendant of passed-in stage primPath
// Make sure that the primPath is a child of the passed in stage's primpath
if (primPath.HasPrefix(inData->primPath)) {
Expand All @@ -1309,8 +1309,6 @@ MStatus MayaUsdProxyShapeBase::computeOutStageData(MDataBlock& dataBlock)
primPath.GetText(),
inData->primPath.GetText());
}
} else {
usdPrim = usdStage->GetPseudoRoot();
}

// Create the output outData
Expand All @@ -1323,7 +1321,7 @@ MStatus MayaUsdProxyShapeBase::computeOutStageData(MDataBlock& dataBlock)

// Set the outUsdStageData
stageData->stage = usdStage;
stageData->primPath = usdPrim ? usdPrim.GetPath() : usdStage->GetPseudoRoot().GetPath();
stageData->primPath = primPath;

//
// set the data on the output plug
Expand Down Expand Up @@ -1907,6 +1905,11 @@ void MayaUsdProxyShapeBase::getDrawPurposeToggles(
_GetDrawPurposeToggles(dataBlock, drawRenderPurpose, drawProxyPurpose, drawGuidePurpose);
}

SdfPath MayaUsdProxyShapeBase::getPrimPath() const
{
return _GetPrimPath(const_cast<MayaUsdProxyShapeBase*>(this)->forceCache());
}

SdfPathVector MayaUsdProxyShapeBase::getExcludePrimPaths() const
{
return _GetExcludePrimPaths(const_cast<MayaUsdProxyShapeBase*>(this)->forceCache());
Expand All @@ -1917,6 +1920,26 @@ size_t MayaUsdProxyShapeBase::getExcludePrimPathsVersion() const
return _excludePrimPathsVersion;
}

SdfPath MayaUsdProxyShapeBase::_GetPrimPath(MDataBlock dataBlock) const
{
MStatus status = MS::kFailure;
const MString primPathStr = dataBlock.inputValue(primPathAttr, &status).asString();
if (!status) {
return SdfPath::EmptyPath();
}

if (primPathStr.length() == 0) {
return SdfPath::AbsoluteRootPath();
} else {
const SdfPath path(primPathStr.asChar());
if (path.IsAbsoluteRootOrPrimPath()) {
return path;
} else {
return SdfPath::EmptyPath();
}
}
}

SdfPathVector MayaUsdProxyShapeBase::_GetExcludePrimPaths(MDataBlock dataBlock) const
{
SdfPathVector ret;
Expand Down
3 changes: 3 additions & 0 deletions lib/mayaUsd/nodes/proxyShapeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ class MayaUsdProxyShapeBase

// Public functions
MAYAUSD_CORE_PUBLIC
virtual SdfPath getPrimPath() const;
MAYAUSD_CORE_PUBLIC
virtual SdfPathVector getExcludePrimPaths() const;
MAYAUSD_CORE_PUBLIC
size_t getExcludePrimPathsVersion() const;
Expand Down Expand Up @@ -393,6 +395,7 @@ class MayaUsdProxyShapeBase

UsdStageRefPtr getUnsharedStage(UsdStage::InitialLoadSet loadSet);

SdfPath _GetPrimPath(MDataBlock dataBlock) const;
SdfPathVector _GetExcludePrimPaths(MDataBlock dataBlock) const;
int _GetComplexity(MDataBlock dataBlock) const;
UsdTimeCode _GetTime(MDataBlock dataBlock) const;
Expand Down
26 changes: 22 additions & 4 deletions lib/mayaUsd/ufe/MayaUsdHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "MayaUsdHierarchy.h"

#include <mayaUsd/fileio/primUpdaterManager.h>
#include <mayaUsd/ufe/Utils.h>

#include <ufe/pathString.h>

Expand Down Expand Up @@ -46,14 +47,31 @@ bool MayaUsdHierarchy::childrenHook(
Ufe::SceneItemList& children,
bool filterInactive) const
{
return mayaUsdHierarchyChildrenHook(child, children, filterInactive);
return mayaUsdHierarchyChildrenHook(sceneItem(), child, children, filterInactive);
}

bool mayaUsdHierarchyChildrenHook(
const PXR_NS::UsdPrim& child,
Ufe::SceneItemList& children,
bool filterInactive)
const Ufe::SceneItem::Ptr& item,
const PXR_NS::UsdPrim& child,
Ufe::SceneItemList& children,
bool filterInactive)
{
const PXR_NS::SdfPath primPath = getProxyShapePrimPath(item->path());
if (primPath.IsEmpty()) {
// An empty primPath means we're in a bad state. We'll return true here
// without populating children.
return true;
}

const PXR_NS::SdfPath& childPath = child.GetPath();
const bool isAncestorOrDescendant
= childPath.HasPrefix(primPath) || primPath.HasPrefix(childPath);
if (!isAncestorOrDescendant) {
// If it is not an ancestor or a descendent, we exclude it from the
// children list.
return true;
}

std::string dagPathStr;
if (MayaUsd::readPullInformation(child, dagPathStr)) {
auto item = Ufe::Hierarchy::createItem(Ufe::PathString::path(dagPathStr));
Expand Down
7 changes: 4 additions & 3 deletions lib/mayaUsd/ufe/MayaUsdHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ class MAYAUSD_CORE_PUBLIC MayaUsdHierarchy : public UsdUfe::UsdHierarchy
//! UsdRootChildHierarchy). These two classes don't share a common base class
//! but they both override UsdHierarchy::childrenHook() with the same code.
bool mayaUsdHierarchyChildrenHook(
const PXR_NS::UsdPrim& child,
Ufe::SceneItemList& children,
bool filterInactive);
const Ufe::SceneItem::Ptr& item,
const PXR_NS::UsdPrim& child,
Ufe::SceneItemList& children,
bool filterInactive);

} // namespace ufe
} // namespace MAYAUSD_NS_DEF
2 changes: 1 addition & 1 deletion lib/mayaUsd/ufe/MayaUsdRootChildHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ bool MayaUsdRootChildHierarchy::childrenHook(
Ufe::SceneItemList& children,
bool filterInactive) const
{
return mayaUsdHierarchyChildrenHook(child, children, filterInactive);
return mayaUsdHierarchyChildrenHook(sceneItem(), child, children, filterInactive);
}

} // namespace ufe
Expand Down
15 changes: 15 additions & 0 deletions lib/mayaUsd/ufe/ProxyShapeHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//
#include "ProxyShapeHierarchy.h"

#include <mayaUsd/nodes/proxyShapeBase.h>
#include <mayaUsd/ufe/Global.h>
#include <mayaUsd/ufe/Utils.h>

Expand Down Expand Up @@ -208,7 +209,21 @@ ProxyShapeHierarchy::createUFEChildList(const UsdPrimSiblingRange& range, bool f
auto parentPath = fItem->path();
Ufe::SceneItemList children;
UFE_V3(std::string dagPathStr;)

const SdfPath primPath = getProxyShapePrimPath(fItem->path());
if (primPath.IsEmpty()) {
// An empty primPath means we're in a bad state. We'll return true here
// without populating children.
return children;
}

for (const auto& child : range) {
const SdfPath& childPath = child.GetPath();
const bool isAncestorOrDescendant
= childPath.HasPrefix(primPath) || primPath.HasPrefix(childPath);
if (!isAncestorOrDescendant) {
continue;
}
#ifdef UFE_V3_FEATURES_AVAILABLE
if (MayaUsd::readPullInformation(child, dagPathStr)) {
auto item = Ufe::Hierarchy::createItem(Ufe::PathString::path(dagPathStr));
Expand Down
12 changes: 10 additions & 2 deletions lib/mayaUsd/ufe/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "Utils.h"

#include <mayaUsd/fileio/jobs/jobArgs.h>
#include <mayaUsd/nodes/proxyShapeBase.h>
#include <mayaUsd/ufe/Global.h>
#include <mayaUsd/ufe/ProxyShapeHandler.h>
#include <mayaUsd/ufe/UsdStageMap.h>
#include <mayaUsd/ufe/Utils.h>
#include <mayaUsd/utils/util.h>

#ifdef UFE_V3_FEATURES_AVAILABLE
Expand Down Expand Up @@ -304,6 +303,15 @@ MayaUsdProxyShapeBase* getProxyShape(const Ufe::Path& path)
return UsdStageMap::getInstance().proxyShapeNode(path);
}

SdfPath getProxyShapePrimPath(const Ufe::Path& path)
{
if (auto proxyShape = getProxyShape(path)) {
return proxyShape->getPrimPath();
}
// No proxy shape. Just default to the empty path.
return SdfPath::AbsoluteRootPath();
}

UsdTimeCode getTime(const Ufe::Path& path)
{
// Path should not be empty.
Expand Down
10 changes: 10 additions & 0 deletions lib/mayaUsd/ufe/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ bool isMayaWorldPath(const Ufe::Path& ufePath);
MAYAUSD_CORE_PUBLIC
PXR_NS::MayaUsdProxyShapeBase* getProxyShape(const Ufe::Path& path);

//! Return the primPath for the gateway node.
//! The gateway node may specify a path that UFE should be restricted to.
//! An empty path is invalid indicates that the path is invalid (i.e. the primPath
//! string has an error or is not a prim path).
//! Otherwise, UFE should only represent paths that are ancestors or descendants
//! of the returned path. Note, if the primPath string is empty, this will
//! SdfPath::AbsoluteRootPath() (instead of an empty SdfPath).
MAYAUSD_CORE_PUBLIC
PXR_NS::SdfPath getProxyShapePrimPath(const Ufe::Path& path);

//! Get the time along the argument path. A gateway node (i.e. proxy shape)
//! along the path can transform Maya's time (e.g. with scale and offset).
MAYAUSD_CORE_PUBLIC
Expand Down
Loading