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

MAYA-115117 Deactivate prim on pull instead of using exclude feature #2036

Merged
merged 1 commit into from
Jan 27, 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
117 changes: 37 additions & 80 deletions lib/mayaUsd/fileio/primUpdaterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <mayaUsd/undo/OpUndoItems.h>
#include <mayaUsd/undo/UsdUndoBlock.h>
#include <mayaUsd/utils/traverseLayer.h>
#include <mayaUsdUtils/util.h>

#include <pxr/base/tf/diagnostic.h>
#include <pxr/base/tf/instantiateSingleton.h>
Expand Down Expand Up @@ -123,18 +124,6 @@ Ufe::Path usdToMaya(const Ufe::Path& usdPath)
return Ufe::PathString::path(dagPathStr);
}

SdfPath ufeToSdfPath(const Ufe::Path& usdPath)
{
auto segments = usdPath.getSegments();

// Can be only a gateway node
if (segments.size() <= 1) {
return {};
}

return SdfPath(segments[1].string());
}

SdfPath makeDstPath(const SdfPath& dstRootParentPath, const SdfPath& srcPath)
{
auto relativeSrcPath = srcPath.MakeRelativePath(SdfPath::AbsoluteRootPath());
Expand Down Expand Up @@ -226,27 +215,14 @@ void removePullInformation(const Ufe::Path& ufePulledPath)
//
bool addExcludeFromRendering(const Ufe::Path& ufePulledPath)
{
auto proxyShape = MayaUsd::ufe::getProxyShape(ufePulledPath);
MStatus status;
MFnDependencyNode depNode(proxyShape->thisMObject(), &status);
CHECK_MSTATUS_AND_RETURN(status, false);

MPlug excludePrimPathsPlug
= depNode.findPlug(MayaUsdProxyShapeBase::excludePrimPathsAttr, &status);
CHECK_MSTATUS_AND_RETURN(status, false);

MString excludePrimPathsStr;
status = excludePrimPathsPlug.getValue(excludePrimPathsStr);
std::vector<std::string> excludePrimPaths = TfStringTokenize(excludePrimPathsStr.asChar(), ",");
UsdPrim prim = MayaUsd::ufe::ufePathToPrim(ufePulledPath);

std::string sdfPathStr = ufeToSdfPath(ufePulledPath).GetText();
if (std::find(excludePrimPaths.begin(), excludePrimPaths.end(), sdfPathStr)
!= excludePrimPaths.end())
return true;
auto stage = prim.GetStage();
if (!stage)
return false;

excludePrimPaths.push_back(sdfPathStr);
excludePrimPathsStr = TfStringJoin(excludePrimPaths, ",").c_str();
excludePrimPathsPlug.setValue(excludePrimPathsStr);
UsdEditContext editContext(stage, stage->GetSessionLayer());
prim.SetActive(false);

return true;
}
Expand All @@ -255,29 +231,21 @@ bool addExcludeFromRendering(const Ufe::Path& ufePulledPath)
//
bool removeExcludeFromRendering(const Ufe::Path& ufePulledPath)
{
auto proxyShape = MayaUsd::ufe::getProxyShape(ufePulledPath);
auto prim = MayaUsd::ufe::ufePathToPrim(ufePulledPath);
std::string sdfPathStr = prim.GetPath().GetText();

MStatus status;
MFnDependencyNode depNode(proxyShape->thisMObject(), &status);
CHECK_MSTATUS_AND_RETURN(status, false);
UsdPrim prim = MayaUsd::ufe::ufePathToPrim(ufePulledPath);

MPlug excludePrimPathsPlug
= depNode.findPlug(MayaUsdProxyShapeBase::excludePrimPathsAttr, &status);
CHECK_MSTATUS_AND_RETURN(status, false);
auto stage = prim.GetStage();
if (!stage)
return false;

MString excludePrimPathsStr;
status = excludePrimPathsPlug.getValue(excludePrimPathsStr);
std::vector<std::string> excludePrimPaths = TfStringTokenize(excludePrimPathsStr.asChar(), ",");
SdfLayerHandle sessionLayer = stage->GetSessionLayer();
UsdEditContext editContext(stage, sessionLayer);

auto foundIt = std::find(excludePrimPaths.begin(), excludePrimPaths.end(), sdfPathStr);
if (foundIt == excludePrimPaths.end())
return true;
// Cleanup the field and potentially empty over
prim.ClearActive();
SdfPrimSpecHandle primSpec = MayaUsdUtils::getPrimSpecAtEditTarget(prim);
if (sessionLayer && primSpec)
sessionLayer->ScheduleRemoveIfInert(primSpec.GetSpec());

excludePrimPaths.erase(foundIt);
excludePrimPathsStr = TfStringJoin(excludePrimPaths, ",").c_str();
excludePrimPathsPlug.setValue(excludePrimPathsStr);
return true;
}

Expand Down Expand Up @@ -539,34 +507,6 @@ PushCustomizeSrc pushExport(
return pushCustomizeSrc;
}

void removePullInfoAndExclusion(
const Ufe::Path& ufePulledPath,
const MDagPath& mayaDagPath,
const UsdMayaPrimUpdaterContext& context)
{
const bool isCopy = context.GetArgs()._copyOperation;
if (isCopy)
return;

FunctionUndoItem::execute(
"Merge to Maya pull info removal",
[ufePulledPath]() {
removePullInformation(ufePulledPath);
return true;
},
[ufePulledPath, mayaDagPath]() {
return writePullInformation(ufePulledPath, mayaDagPath);
});

FunctionUndoItem::execute(
"Merge to Maya rendering inclusion",
[ufePulledPath]() {
removeExcludeFromRendering(ufePulledPath);
return true;
},
[ufePulledPath]() { return addExcludeFromRendering(ufePulledPath); });
}

//------------------------------------------------------------------------------
//
SdfPath getDstSdfPath(const Ufe::Path& ufePulledPath, const SdfPath& srcSdfPath, bool isCopy)
Expand Down Expand Up @@ -856,12 +796,29 @@ bool PrimUpdaterManager::mergeToUsd(
ctxArgs,
std::get<UsdPathToDagPathMapPtr>(pushCustomizeSrc));

if (!isCopy) {
FunctionUndoItem::execute(
"Merge to Maya rendering inclusion",
[pulledPath]() {
removeExcludeFromRendering(pulledPath);
return true;
},
[pulledPath]() { return addExcludeFromRendering(pulledPath); });
}

if (!pushCustomize(pulledPath, pushCustomizeSrc, customizeContext)) {
return false;
}

// Remove the pull information and node exclusion.
removePullInfoAndExclusion(pulledPath, mayaDagPath, context);
if (!isCopy) {
FunctionUndoItem::execute(
"Merge to Maya pull info removal",
[pulledPath]() {
removePullInformation(pulledPath);
return true;
},
[pulledPath, mayaDagPath]() { return writePullInformation(pulledPath, mayaDagPath); });
}

// Discard all pulled Maya nodes.
std::vector<MDagPath> toApplyOn = UsdMayaUtil::getDescendantsStartingWithChildren(mayaDagPath);
Expand Down
34 changes: 18 additions & 16 deletions lib/mayaUsd/ufe/ProxyShapeHierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ namespace {

// We want to display the unloaded prims, so removed UsdPrimIsLoaded from
// the default UsdPrimDefaultPredicate.
const Usd_PrimFlagsConjunction MayaUsdPrimDefaultPredicate
= UsdPrimIsActive && UsdPrimIsDefined && !UsdPrimIsAbstract;
const Usd_PrimFlagsConjunction MayaUsdPrimDefaultPredicate = UsdPrimIsDefined && !UsdPrimIsAbstract;
Copy link
Author

Choose a reason for hiding this comment

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

I wish the predicate in USD be more flexible!


UsdPrimSiblingRange getUSDFilteredChildren(
const UsdPrim& prim,
Expand Down Expand Up @@ -133,12 +132,12 @@ Ufe::SceneItem::Ptr ProxyShapeHierarchy::sceneItem() const { return fItem; }

bool ProxyShapeHierarchy::hasChildren() const
{
const UsdPrim& rootPrim = getUsdRootPrim();
if (!rootPrim.IsValid()) {
UFE_LOG("invalid root prim in ProxyShapeHierarchy::hasChildren()");
return false;
}
return !getUSDFilteredChildren(rootPrim).empty();
// We have an extra logic in createUFEChildList to remap and filter
// prims. Going this direction is more costly, but easier to maintain.
//
// I don't have data that proves we need to worry about performance in here,
// so going after maintainablility.
return !children().empty();
}

Ufe::SceneItemList ProxyShapeHierarchy::children() const
Expand All @@ -148,7 +147,7 @@ Ufe::SceneItemList ProxyShapeHierarchy::children() const
if (!rootPrim.IsValid())
return Ufe::SceneItemList();

return createUFEChildList(getUSDFilteredChildren(rootPrim));
return createUFEChildList(getUSDFilteredChildren(rootPrim), true);
}

#ifdef UFE_V2_FEATURES_AVAILABLE
Expand All @@ -166,7 +165,7 @@ Ufe::SceneItemList ProxyShapeHierarchy::filteredChildren(const ChildFilter& chil
Usd_PrimFlagsPredicate flags = childFilter.front().value
? UsdPrimIsDefined && !UsdPrimIsAbstract
: MayaUsdPrimDefaultPredicate;
return createUFEChildList(getUSDFilteredChildren(rootPrim, flags));
return createUFEChildList(getUSDFilteredChildren(rootPrim, flags), false);
}

UFE_LOG("Unknown child filter");
Expand All @@ -175,7 +174,8 @@ Ufe::SceneItemList ProxyShapeHierarchy::filteredChildren(const ChildFilter& chil
#endif

// Return UFE child list from input USD child list.
Ufe::SceneItemList ProxyShapeHierarchy::createUFEChildList(const UsdPrimSiblingRange& range) const
Ufe::SceneItemList
ProxyShapeHierarchy::createUFEChildList(const UsdPrimSiblingRange& range, bool filterInactive) const
{
// We must create selection items for our children. These will have as
// path the path of the proxy shape, with a single path segment of a
Expand All @@ -192,11 +192,13 @@ Ufe::SceneItemList ProxyShapeHierarchy::createUFEChildList(const UsdPrimSiblingR
}
} else {
#endif
children.emplace_back(UsdSceneItem::create(
parentPath
+ Ufe::PathSegment(
Ufe::PathComponent(child.GetName().GetString()), g_USDRtid, '/'),
child));
if (!filterInactive || child.IsActive()) {
children.emplace_back(UsdSceneItem::create(
parentPath
+ Ufe::PathSegment(
Ufe::PathComponent(child.GetName().GetString()), g_USDRtid, '/'),
child));
}
#ifdef UFE_V3_FEATURES_AVAILABLE
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion lib/mayaUsd/ufe/ProxyShapeHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ class MAYAUSD_CORE_PUBLIC ProxyShapeHierarchy : public Ufe::Hierarchy

private:
const PXR_NS::UsdPrim& getUsdRootPrim() const;
Ufe::SceneItemList createUFEChildList(const PXR_NS::UsdPrimSiblingRange& range) const;
Ufe::SceneItemList
createUFEChildList(const PXR_NS::UsdPrimSiblingRange& range, bool filterInactive) const;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Negative boolean tend to be confusing. I would prefere this to be filter with true meaning do filter, false meaning do not filter.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, it mean filter-the-inactive-nodes and not make-filter-inactive... I mis-read the meaning of the variable.


private:
Ufe::SceneItem::Ptr fItem;
Expand Down
10 changes: 10 additions & 0 deletions test/lib/mayaUsd/fileio/testMergeToUsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ def testTransformMergeToUsd(self):
with mayaUsd.lib.OpUndoItemList():
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.mergeToUsd(aMayaPathStr))

# Edit will re-allocate anything that was under pulled prim due to deactivation
# Grab new references for /A/B prim
bUsdPrim = mayaUsd.ufe.ufePathToPrim(bUsdUfePathStr)
bXlateOp = UsdGeom.Xformable(bUsdPrim).GetOrderedXformOps()[0]

# Check that edits have been preserved in USD.
for (usdUfePathStr, mayaMatrix, xlateOp) in \
zip([aUsdUfePathStr, bUsdUfePathStr], [aMayaMatrix, bMayaMatrix],
Expand Down Expand Up @@ -158,6 +163,11 @@ def testTransformMergeToUsdUndoRedo(self):
cmds.mayaUsdMergeToUsd(aMayaPathStr)

def verifyMergeToUsd():
# Edit will re-allocate anything that was under pulled prim due to deactivation
# Grab new references for /A/B prim
bUsdPrim = mayaUsd.ufe.ufePathToPrim(bUsdUfePathStr)
bXlateOp = UsdGeom.Xformable(bUsdPrim).GetOrderedXformOps()[0]

# Check that edits have been preserved in USD.
for (usdUfePathStr, mayaMatrix, xlateOp) in \
zip([aUsdUfePathStr, bUsdUfePathStr], [aMayaMatrix, bMayaMatrix],
Expand Down