Skip to content

Commit

Permalink
Merge pull request #3807 from jufrantz/fix_display_layer_membership_p…
Browse files Browse the repository at this point in the history
…ushs

Fix display layer loss when merging/duplicating to USD
  • Loading branch information
seando-adsk authored Jun 13, 2024
2 parents 0e8a3e0 + c1b7602 commit 92aea58
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 34 deletions.
37 changes: 35 additions & 2 deletions lib/mayaUsd/fileio/primUpdaterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,6 @@ PushCustomizeSrc pushExport(
auto usdPathToDagPathMap = std::make_shared<UsdPathToDagPathMap>();
for (const auto& v : writeJob.GetDagPathToUsdPathMap()) {
usdPathToDagPathMap->insert(UsdPathToDagPathMap::value_type(v.second, v.first));
context._pushExtras.processItem(v.first, v.second);
}

std::get<UsdPathToDagPathMapPtr>(pushCustomizeSrc) = usdPathToDagPathMap;
Expand All @@ -620,6 +619,26 @@ PushCustomizeSrc pushExport(
return pushCustomizeSrc;
}

//------------------------------------------------------------------------------
//
void processPushExtras(
const MayaUsd::ufe::ReplicateExtrasToUSD& pushExtras,
const UsdPathToDagPathMap& srcDagPathMap,
const SdfPath& srcRootPath,
const SdfPath& dstRootPath)
{
if (srcRootPath == dstRootPath) {
for (const auto& srcPaths : srcDagPathMap) {
pushExtras.processItem(srcPaths.second, srcPaths.first);
}
} else {
for (const auto& srcPaths : srcDagPathMap) {
const auto dstPrimPath = srcPaths.first.ReplacePrefix(srcRootPath, dstRootPath);
pushExtras.processItem(srcPaths.second, dstPrimPath);
}
}
}

//------------------------------------------------------------------------------
//
SdfPath getDstSdfPath(const Ufe::Path& ufePulledPath, const SdfPath& srcSdfPath, bool isCopy)
Expand Down Expand Up @@ -1094,10 +1113,18 @@ bool PrimUpdaterManager::mergeToUsd(
auto pushCustomizeSrc = pushExport(pulledPath, depNodeFn.object(), context);
progressBar.advance();

const auto& srcDagPathMap = std::get<UsdPathToDagPathMapPtr>(pushCustomizeSrc);

if (TF_VERIFY(srcDagPathMap)) {
const auto& srcRootPath = std::get<SdfPath>(pushCustomizeSrc);
const auto dstRootPath = getDstSdfPath(pulledPath, srcRootPath, isCopy);
processPushExtras(context._pushExtras, *srcDagPathMap, srcRootPath, dstRootPath);
}

// 2) Traverse the in-memory layer, creating a prim updater for each prim,
// and call Push for each updater. Build a new context with the USD path
// to Maya path mapping information.
context.SetUsdPathToDagPathMap(std::get<UsdPathToDagPathMapPtr>(pushCustomizeSrc));
context.SetUsdPathToDagPathMap(srcDagPathMap);

if (!isCopy) {
if (!FunctionUndoItem::execute(
Expand Down Expand Up @@ -1631,6 +1658,12 @@ bool PrimUpdaterManager::duplicate(
const SdfPath srcParentPath = srcRootPath.GetParentPath();
const SdfPath dstParentPath = dstParentPrim.GetPath();

const auto& srcPathMapPtr = std::get<UsdPathToDagPathMapPtr>(pushExportOutput);

if (TF_VERIFY(srcPathMapPtr)) {
processPushExtras(context._pushExtras, *srcPathMapPtr, srcParentPath, dstParentPath);
}

CopyLayerPrimsOptions options;
options.progressBar = &progressBar;

Expand Down
95 changes: 63 additions & 32 deletions test/lib/ufe/testDisplayLayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def testDisplayLayerDuplicate(self):
layerObjs = cmds.editDisplayLayerMembers(self.LAYER1, query=True, **self.kwArgsEditDisplayLayerMembers)
XFORM1_CUBE2 = '|stage1|stageShape1,/Xform1/Cube2'
self.assertTrue(XFORM1_CUBE2 in layerObjs)
self._testLayerFromPath(XFORM1_CUBE2, self.LAYER1)
self._testLayerFromPath(XFORM1_CUBE2, self.LAYER1)

def testDisplayLayerClear(self):
cmdHelp = cmds.help('editDisplayLayerMembers')
Expand Down Expand Up @@ -437,37 +437,68 @@ def testDisplayLayerClear(self):

def testDisplayLayerEditAsMaya(self):
'''Display layer membership in Edit As Maya workflow.'''

(ps, xlateOp, xlation, aUsdUfePathStr, aUsdUfePath, aUsdItem,
_, _, _, _, _) = createSimpleXformScene()

# Add an item to a new display layer
cmds.createDisplayLayer(name='layer1', number=1, empty=True)
cmds.editDisplayLayerMembers('layer1', '|stage1|stageShape1,/A', noRecurse=True)

# Edit aPrim as Maya data.
with mayaUsd.lib.OpUndoItemList():
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.canEditAsMaya(aUsdUfePathStr))
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.editAsMaya(aUsdUfePathStr))

# Check display layer membership on the other side
layerObjs = cmds.editDisplayLayerMembers('layer1', query=True, **self.kwArgsEditDisplayLayerMembers)
self.assertTrue("|__mayaUsd__|AParent|A" in layerObjs)

# Create a new layer and put the item there
cmds.createDisplayLayer(name='layer2', number=1, empty=True)
cmds.editDisplayLayerMembers('layer2', "|__mayaUsd__|AParent|A", noRecurse=True)

# Merge edits back to USD.
aMayaItem = ufe.GlobalSelection.get().front()
aMayaPath = aMayaItem.path()
aMayaPathStr = ufe.PathString.string(aMayaPath)
with mayaUsd.lib.OpUndoItemList():
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.mergeToUsd(aMayaPathStr))

# Check display layer membership back on the USD side
layerObjs = cmds.editDisplayLayerMembers('layer2', query=True, **self.kwArgsEditDisplayLayerMembers)
self.assertTrue('|stage1|stageShape1,/A' in layerObjs)
(_,
_, _, aUsdUfePathStr, _, _,
_, _, bUsdUfePathStr, _, _) = createSimpleXformScene()

def editAsMaya(usdUfePathStr):
with mayaUsd.lib.OpUndoItemList():
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.canEditAsMaya(usdUfePathStr))
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.editAsMaya(usdUfePathStr))
aMayaItem = ufe.GlobalSelection.get().front()
aMayaPath = aMayaItem.path()
return ufe.PathString.string(aMayaPath)

def mergeToUsd(mayaPathStr):
with mayaUsd.lib.OpUndoItemList():
self.assertTrue(mayaUsd.lib.PrimUpdaterManager.mergeToUsd(mayaPathStr))

def duplicateToUsd(mayaPathStr, usdUfePathStr):
with mayaUsd.lib.OpUndoItemList():
mayaUsd.lib.PrimUpdaterManager.duplicate(mayaPathStr, usdUfePathStr)

def verifyInDisplayLayers(layerNameAndMembers):
# Verify they are in layer.
for name, members in layerNameAndMembers.items():
# Verify they are in layer.
layerObjs = cmds.editDisplayLayerMembers(name, query=True, **self.kwArgsEditDisplayLayerMembers)
for member in members:
print(member)
self.assertTrue(member in layerObjs)

def createDisplayLayers(layerNameAndMembers):
for name, members in layerNameAndMembers.items():
cmds.createDisplayLayer(name=name, number=1, empty=True)
cmds.editDisplayLayerMembers(name, members, noRecurse=True)
verifyInDisplayLayers(layerNameAndMembers)

# Verify that displayLayers survive editing the stage's root.
createDisplayLayers({"lyrA": [aUsdUfePathStr], "lyrB": [bUsdUfePathStr]})
aMayaPathStr = editAsMaya(aUsdUfePathStr)
verifyInDisplayLayers({"lyrA": [aMayaPathStr], "lyrB": [aMayaPathStr + "|B"]})

# Verify that displayLayers survive merging to USD root.
createDisplayLayers({"lyrA2": [aMayaPathStr], "lyrB2": [aMayaPathStr + "|B"]})
mergeToUsd((aMayaPathStr))
verifyInDisplayLayers({"lyrA2": [aUsdUfePathStr], "lyrB2": [bUsdUfePathStr]})

# Verify that displayLayers survive editing non-root prim.
createDisplayLayers({"lyrB3": [bUsdUfePathStr]})
bMayaPathStr = editAsMaya(bUsdUfePathStr)
verifyInDisplayLayers({"lyrB3": [bMayaPathStr]})

# Verify that displayLayers survive merging to non-root prim.
createDisplayLayers({"lyrB4": [bMayaPathStr]})
mergeToUsd((bMayaPathStr))
verifyInDisplayLayers({"lyrB4": [bUsdUfePathStr]})

# Verify that displayLayers survive duplicating to non-root prim.
cubeName = cmds.polyCube()[0]
cubeMayaPathStr = cmds.ls(cubeName, long=True)[0]

createDisplayLayers({"lyrC": [cubeMayaPathStr]})
duplicateToUsd(cubeMayaPathStr, bUsdUfePathStr)
verifyInDisplayLayers({"lyrC": [cubeMayaPathStr, bUsdUfePathStr + "/" + cubeName]})

@unittest.skipUnless(mayaUtils.ufeSupportFixLevel() >= 3, "Requires Display Layer Ufe subtree invalidate fix.")
def testDisplayLayerSubtreeInvalidate(self):
Expand Down

0 comments on commit 92aea58

Please sign in to comment.