-
Notifications
You must be signed in to change notification settings - Fork 202
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-112039 - As a user, I'd like to have an unshareable stage #1455
Conversation
1) ProxyShape Changes - Adding New unsharable workflow - Main idea is we create a new (unshared) root and put the incoming source as a sublayer, thereby having the ability to sandbox your changes - Exposed new attribute for the unshared composition (needed for layer management) - There's an unshared SDF layer on the proxy (private member) which stores the data so that the user can toggle on and off without losing their data - Since we have the ability to create new layers under this new unshared root, we need to keep track of the "unshared layers" and the source layers. That data (layer list) is stored as metadata on the unshared composition root. - Saving on disk follows the same mechanism that it normally would, but as you will see in the save portion we have added some special handling for unshared comp layers (saved in maya file) - Also added a bunch of helper functions to Util save/load layer metadata and have a shared token - Adding Ability to know if the Stage or Layer is incoming - By incoming I mean the stage is coming in from a connection, for example the instage data or the cache Id - This is needed since we want to have special handling for these stages. For example incoming stages should NOT be saved and show up differently in the layer edtior - Also added a bunch of helper functions to Util to be able to get all the layers recursively so we know if a layer is incoming. 2) Save Changes - Moving some of the shared code between saveToUSD and SaveToMayaFile into separate local functions - Refactor the getStagesToSave to Actually be getProxiesToSave, other than the naming, Tim had already started this, but what I did here is instead of walking the stages to determine which ones are dirty, I walk the proxies and determine which ones need saving, also I don't walk the proxies again when we do the savetousd or savetomaya, which should be a performance improvement (insignificant probably) - We skip saving incoming Layers, here you will see I added the concept of Stub, so I save empty layer data and this is needed so that I can keep track of where the user moves these "incoming layers" in the hierarchy. - Unshared comp layers are saved to maya file ALWAYS. Similar to the session layer the unshared comp layers always get saved into the maya file, so I put a special case to not prompt the user for changes when the changes are only in a layer that gets saved to maya file. NOTE: I did NOT fix this for the session layer. 3) Layer Editor Changes - Adding the concept of ReadOnly Layers - For now the read only layers are the incoming layers in the stage - For UI I'm using the same UI as the mute - These Readonly layers cannot be moved unless you are moving the parent readonly layer in the tree that contains both readonly and non-readonly layers - Exposing new functions on the command hook to ask the proxy if the stage is coming from an incoming source and if its also using the unshared composition workflow
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.
Not quite as familiar as I'd like to be with the workflow and how it connects to the data model and implementation, so my review doesn't have enough depth to stand on its own. Otherwise looks good to me.
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.
Overall very good job. Just a few comments and suggestions.
} | ||
} | ||
|
||
serializedHandle.setString(UsdMayaUtil::convert(temp)); |
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.
Should we be setting this when status == MS:kFailure (from line 497). Won't temp be bad?
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.
Yes, but this is the old behavior, I didn't want to change it.. But I agree with you
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.
Let me know if I should change it
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.
Still have ProxyShape changes to review, but posting everything else that I have reviewed already.
@@ -179,5 +179,93 @@ def testDuplicateProxyStageFileBacked(self): | |||
self.assertEqual(0, len(ufe.Hierarchy.hierarchy(duplProxyShapeItem).children())) | |||
self.assertEqual(0, len(ufe.Hierarchy.hierarchy(treebaseItem).children())) | |||
|
|||
def testShareStage(self): |
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.
Few more tests to add in here:
- serialization with complex layer stack on the downstream proxy
- upstream stage src changes, e.g. change file paths on the src proxy and make sure edits are preserved AND layer stack is preserved as well
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.
Added more tests!
return status; | ||
} | ||
|
||
MStatus setValueForAttr(const MObject& node, const MObject& attribute, const std::string& value) |
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.
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.
No, its using the MObject not the attribute name. But nice one! Would have used it!
Co-authored-by: Sean Donnelly <23455376+seando-adsk@users.noreply.github.com>
Co-authored-by: Krystian Ligenza <krystian.ligenza@autodesk.com>
@ppt-adsk @seando-adsk @kxl-adsk I updated with regards to your comments, apologies for resolving them on my side, it was my way of keeping track of them but moving forward I will let the person who puts the comment resolve it. Let me know if you have any questions. |
lib/mayaUsd/nodes/proxyShapeBase.cpp
Outdated
|
||
// Share the stage | ||
if (sharableStage) { | ||
if (isIncomingStage) { |
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.
We are only introducing a new mode and shouldn't change the behavior of the sharable mode. Please remove this change of edit target.
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.
Done!
for (const auto& identifier : subLayerIds) { | ||
SdfLayerRefPtr sublayer = SdfLayer::Find(identifier); | ||
if (sublayer) { | ||
_unsharedStageRootSublayers.push_back(sublayer); |
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.
Why these layers don't get into UsdMayaStageCache?
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.
Its simpler to keep pointers to them, putting them in the cache I will have to keep track of the id and remove them once i'm done with them or we leak (grow the cache).
lib/mayaUsd/nodes/proxyShapeBase.h
Outdated
@@ -126,6 +129,8 @@ class MayaUsdProxyShapeBase | |||
static MObject outStageDataAttr; | |||
MAYAUSD_CORE_PUBLIC | |||
static MObject outStageCacheIdAttr; | |||
MAYAUSD_CORE_PUBLIC | |||
static MObject outIsStageIncomingAttr; |
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.
We already have a vector of all incoming layers, this attribute shouldn't be necessary. In isStageIncoming, you will check if incoming layers are not empty.
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.
OK no worries I removed it. I had it for the test, but now I also removed those tests.
lib/mayaUsd/nodes/proxyShapeBase.h
Outdated
|
||
// Keep track of source stage's root identifier (when we change the source we can swap it | ||
// in-place in the layer heirarchy) | ||
std::string _sourceRootIdentifier; |
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.
I'm not sure I understand the need for this identifier? You are already holding onto the stage root layer.
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.
This is because I need to keep track of the source. On the proxy shape the source can be one of 4 things:
- Stage Data In port
- Stage Cache ID In Port
- File Path (Valid)
- New Anon Stage (if all else fails)
So when you are in unshared mode that source above is greyed out but you can still move it in the hierarchy. Meaning you can have
UnsharedRootLayer
|---> Some User Created Middle Layer
|---> The source (referenced above, buried in a complex hierarchy)
So now when we change the file or change the source we want to maintain that hierarchy, so we need to keep track of what the source was and what it will be.
After our discussion yesterday I was trying to access the old stage from the out port, but its hard for me to figure out which layer is which, the code gets really complicated if you don't want to keep track of the source layer. Simplest thing is to keep it as is.
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.
Done
lib/mayaUsd/nodes/proxyShapeBase.cpp
Outdated
CHECK_MSTATUS_AND_RETURN_IT(retValue); | ||
if (!remappedLayers.empty()) { | ||
for (auto sublayer : sublayers) { | ||
remapSublayerRecursive(sublayer, remappedLayers); |
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.
During iteration, you can discover that all layers were remapped. So you can save both searching for layers, vector insert and calls to remapSublayerRecursive if you do something like:
if (remappedLayers.empty())
return;
for(const auto& sublayerPath : sublayerPaths) {
SdfLayerRefPtr subLayer = SdfLayer::Find(sublayerPath);
remapSublayerRecursive(sublayer, remappedLayers);
if (remappedLayers.empty())
return;
}
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.
Done
… crasher and adding new test
@kxl-adsk done! |
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.
Thank you. LGTM.
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.
Overall looks good - just a couple of minor changes.
@@ -54,7 +59,40 @@ MString executeMel(const std::string& commandString) | |||
// maya doesn't support spaces in undo chunk names... | |||
MString cleanChunkName(QString name) { return quote(name.replace(" ", "_").toStdString()).c_str(); } | |||
|
|||
std::string GetProxyShapeName(const std::string& proxyShapePath) |
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.
This function and the one below should be "lowerCamelCase" so "get" not "Get"
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.
Done!
@seando-adsk Done! |
ProxyShape Changes
Adding New unsharable workflow
Adding Ability to know if the Stage or Layer is incoming
Save Changes
Layer Editor Changes