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

USDMaya: Layer modifications preserved after stage cache cleared #57

Closed
murphyeoin opened this issue Sep 16, 2016 · 8 comments
Closed

Comments

@murphyeoin
Copy link
Contributor

Hello, if we take the file below, save it as cube.usd, and run the code beneath it we see that the cube.usd layer, when re-loaded, remains modified, rather than reverting to it's virgin (xform at the origin) state as we would expect.
We've tried manually clearing the stage cache etc - makes no differerence. We're thinking that this might be to do with the layer cache (which we don't seem to heave easy access). Is this possibly desired behaviour? If so, would be good to at least have a way of forcing our desired behaviour (use case - user build a scene in USDMaya, makes modifications to the USD data in memory, decides to restart their work from scratch, creates new empty scene in maya, builds scene again)

'

usda 1.0

(
defaultPrim = "World"
)

def "World"
{
def Mesh "Cube"
{
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)]
}
}
'

`
from pxr import UsdGeom

from maya import cmds
from pxr import UsdMaya

cmds.loadPlugin('pxrUsd')
cmds.file(new=True, force=True)

'''
Using maya to open the layer for modification but could as easily do it with pure USD API
'''
proxy = cmds.createNode("pxrUsdProxyShape")
cmds.setAttr("%s.filePath" % proxy, "cube.usd", type="string")
theStageCache = UsdMaya.StageCache.Get()
stages = theStageCache.GetAllStages()
stage = stages[0]

'''
Modify the transform in a fairly obvious way
(I'm sure there's a nicer way to do this!)
'''
prim = stage.GetPrimAtPath('/World/Cube')
geo = UsdGeom.Xformable(prim)
op = geo.MakeMatrixXform()
matrix = op.GetOpTransform(0)
translate = matrix.ExtractTranslation()
translate[2] = translate[2]-20
matrix.SetTranslate(translate)
op.Set(matrix, 0)

'''
Now create a new maya scene, reopen the layer, and you will see that the
cube is still in it's modified position (rather than at the origin)
'''
cmds.file(new=True, force=True)
proxy = cmds.createNode("pxrUsdProxyShape")
cmds.setAttr("%s.filePath" % proxy, "cube.usd", type="string")
`

@jtran56
Copy link

jtran56 commented Sep 16, 2016

Filed as internal issue #137455.

@spiffmon
Copy link
Member

Hi Eoin,
Good observation that starting a new Maya scene should cause all state to be flushed, including the StageCache. Does Maya have a hook we can latch onto at "New" to clear the StageCache?

You should never need to worry about the Sdf_LayerRegistry, because it only holds weak references to SdfLayers, and therefore will never keep them alive - that's what allows us to keep the registry as an internal detail.
If you have verified that the StageCache is indeed being flushed (you can set the TF_DEBUG env var to "USD_STAGE_CACHE" for diagnostics), then my suspicion is that either the PluginStaticData for the maya usd proxyShape is not being released (it holds a strong pointer to the stage), or Maya is not guaranteeing that the old nodes are fully decomissioned prior to creating any new nodes.
I don't know anything about Maya plugin object lifetime management, but I'll check with our experts.

Cheers,
--spiff

@murphyeoin
Copy link
Contributor Author

Hi Spiff,
the stageCache is being cleared on maya new scene/open scene/close scene events, that's working OK
Thanks for the insight into the layerRegistry behaviour - makes sense.

One of our Maya gurus has already fingered MpxData (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/Maya-SDK/cpp-ref/class-m-px-data-html.html) as a likely suspect, and it's derived type MPxGeometryData is used in https:/PixarAnimationStudios/USD/blob/2eb01f5cd4c2dae4e1ef9912ca27a93083bb6ef4/third_party/maya/lib/usdMaya/stageData.h... so it sounds like the culprit might either be in PluginStaticData or stageData... I will follow up with him tomorrow, but would be great to see if anyone at Pixar has any ideas - can also talk to the Autodesk Maya peeps and see what they think.
Thanks!
Eoin

@murphyeoin
Copy link
Contributor Author

Hi Spiff and the rest of team USD,
did a bit more digging into this, and it looks like maybe the MPxData is not responsible after all (although not definitive)

If I run my code above that mutates the layer, then I do

from maya import cmds
cmds.file(new=True, force=True)
cmds.unloadPlugin('pxrUsd')

Then -

from pxr import Sdf
layers = Sdf.Layer.GetLoadedLayers()
for currLayer in layers:
    print currLayer

we can see that it's still hanging onto the layer we originally loaded, plus it's session layer, even though the USDMaya plugin is unloaded.
What's nasty is that the session layers keep accumulating (as a new one is created for each session) on each file new.
I did put some print statements in the USDMaya plugin to see if things were being destroyed correctly - and it mostly looked like they were... but that's not definitive

Luckily, I now have a workaround, which is on file close/new event, I can run something like this (or the C++ equivalent)

layers = Sdf.Layer.GetLoadedLayers()
for l in layers:
    l.Reload()

Thanks

@spiffmon
Copy link
Member

spiffmon commented Oct 1, 2016

Hey Eoin,
Matt Johnson found the problem - something in our maya imaging adapter was not getting reset properly and hanging onto strong pointers to the stage. Fix is IP.

--spiff

On Sep 25, 2016, at 9:54 PM, murphyeoin [email protected] wrote:

Hi Spiff and the rest of team USD,
did a bit more digging into this, and it looks like maybe the MPxData is not responsible after all (although not definitive)

If I run my code above that mutates the layer, then I do

from maya import cmds
cmds.file(new=True, force=True)
cmds.unloadPlugin('pxrUsd')
Then -

from pxr import Sdf
layers = Sdf.Layer.GetLoadedLayers()
for currLayer in layers:
print currLayer
we can see that it's still hanging onto the layer we originally loaded, plus it's session layer, even though the USDMaya plugin is unloaded.
What's nasty is that the session layers keep accumulating (as a new one is created for each session) on each file new.
I did put some print statements in the USDMaya plugin to see if things were being destroyed correctly - and it mostly looked like they were... but that's not definitive

Luckily, I now have a workaround, which is on file close/new event, I can run something like this (or the C++ equivalent)

layers = Sdf.Layer.GetLoadedLayers()
for l in layers:
l.Reload()
Thanks


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@murphyeoin
Copy link
Contributor Author

Hi Spiff.. great! Send our thanks to Matt for figuring that one out - a few of us spent a couple of hours on it with no luck.
Thanks
Eoin

@sunyab
Copy link
Contributor

sunyab commented Nov 28, 2016

This issue should be fixed by commit 3482797 in the dev branch.

@sunyab
Copy link
Contributor

sunyab commented Dec 10, 2016

Commit has been merged into release v0.7.2, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants