-
Notifications
You must be signed in to change notification settings - Fork 201
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
EMSUSD-499 - Dirty layers don't get saved in Maya files #3402
Conversation
|
||
// Check what is the cache connected to | ||
MStringArray result; | ||
MGlobal::executeCommand(("listConnections -shapes on " + this->name()), result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @samuelliu-adsk , thanks for working on this for the issue #3243. I tested it but unfortunately it doesn't resolve the issue due to the following code:
MGlobal::executeCommand(("listConnections -shapes on " + this->name()), result);
This is because a mayaUsdProxyShape
usually has a time1
node's connection to its time
attribute. The maya-usd code base does this as well. Please see https://github.com/Autodesk/maya-usd/blob/dev/plugin/adsk/scripts/mayaUsd_createStageWithNewLayer.py#L39 and https://github.com/Autodesk/maya-usd/blob/dev/lib/mayaUsd/ufe/UsdUndoCreateStageWithNewLayerCommand.cpp#L150-L151. Hence, MGlobal::executeCommand(("listConnections -shapes on " + this->name()), result)
would return a time1
node and the isIncomingStage
would be set to true
which is not correct. I guess you might have been using the example code on the issue page #3243 to test the solution but the code example is missing time1
node's connection. Sorry for that.
According to the logic we discussed on the issue page:
If "mayaUsdProxyShape.stageCacheId" is connected, don't save, else if the stageCacheId refer an existing stage save its content.
I would suggest the following solution (I tested it and it resolves the issue):
bool isIncomingStage = false;
if (!inDataHandle.data().isNull()) {
isIncomingStage = true;
}
This is because the !inDataHandle.data().isNull()
check already takes care of checking whether the proxy shape has an incoming connection to its inStageData
attribute which might be from a bifrost graph or another proxy shape node. If there is no connection to it then we can consider isIncomingStage
is false. I don't think we need to check the stageCacheId
value because if it has value and is valid and in USD stage cache then isIncomingStage
should be false. And if stageCacheId
value is set but it's not valid then isIncomingStage
should be false too.
I did a test for our internal patch which you could use to test as well:
from pxr import Usd, UsdUtils, UsdGeom
from maya import cmds
import mayaUsd.lib
import tempfile
# you can find this file in maya-usd repo: maya-usd/test/lib/mayaUsd/nodes/ProxyShapeBaseTest/CubeModel.usda
filePath = '/home/users/nickw/Test/CubeModel.usda'
stageCache = UsdUtils.StageCache.Get()
with Usd.StageCacheContext(stageCache):
cachedStage = Usd.Stage.Open(filePath)
stageId = stageCache.GetId(cachedStage).ToLongInt()
shapeNode = cmds.createNode('mayaUsdProxyShape')
cmds.connectAttr('time1.outTime', '{}.time'.format(shapeNode))
cmds.setAttr('{}.stageCacheId'.format(shapeNode), stageId)
cachedStage.SetEditTarget(cachedStage.GetSessionLayer())
fullPath = cmds.ls(shapeNode, long=True)[0]
cmds.select("{},/CubeModel".format(fullPath))
# Move the cube prim
cmds.move(0, 0, 2, r=True)
# Make sure shareStage is ON
assert cmds.getAttr('{}.{}'.format(shapeNode,"shareStage"))
# Make sure there is no connection to inStageData
assert not cmds.listConnections('{}.inStageData'.format(shapeNode), s=True, d=False)
cmds.select(cmds.listRelatives(fullPath, p=True)[0], r=True)
with tempfile.TemporaryDirectory(prefix='ProxyShapeBase') as testDir:
pathToSave = "{}/CubeModel.ma".format(testDir)
cmds.file(rename=pathToSave)
cmds.file(save=True, force=True, type='mayaAscii')
cmds.file(new=True, force=True)
cmds.file(pathToSave, force=True, open=True)
stage = mayaUsd.lib.GetPrim(fullPath).GetStage()
prim = stage.GetPrimAtPath('/CubeModel')
assert prim.IsValid()
# Verify we get the saved changes we did
xform = UsdGeom.Xformable(prim)
translate = xform.GetOrderedXformOps()[0].Get()
assert translate[2] == 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @NickWu , I'll make a new PR with the fixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @samuelliu-adsk , thanks for working on this. I forgot to add the code to connect time1
again. I have updated the test code with this line cmds.connectAttr('time1.outTime', '{}.time'.format(shapeNode))
For details and discussions please see this github issue: #3243
The idea is to check if the cache is actually connected (for example bifrost graph), if not this is not actually an incoming stage