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-112039 - As a user, I'd like to have an unshareable stage #1455

Merged
merged 12 commits into from
Jul 10, 2021

Conversation

alsoussi
Copy link
Contributor

@alsoussi alsoussi commented Jun 3, 2021

  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

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
@kxl-adsk kxl-adsk requested review from ppt-adsk and removed request for spinell-adsk and fowlertADSK June 9, 2021 16:28
@kxl-adsk kxl-adsk added proxy Related to base proxy shape workflows Related to in-context workflows labels Jun 9, 2021
@kxl-adsk kxl-adsk requested a review from fowlertADSK June 9, 2021 16:37
Copy link
Collaborator

@ppt-adsk ppt-adsk left a 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.

lib/mayaUsd/commands/Readme.md Outdated Show resolved Hide resolved
lib/mayaUsd/commands/Readme.md Outdated Show resolved Hide resolved
lib/mayaUsd/commands/abstractLayerEditorWindow.h Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/proxyShapeBase.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@seando-adsk seando-adsk left a 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.

lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
}
}

serializedHandle.setString(UsdMayaUtil::convert(temp));
Copy link
Collaborator

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?

Copy link
Contributor Author

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

Copy link
Contributor Author

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

lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/proxyShapeBase.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/proxyShapeBase.cpp Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/mayaCommandHook.cpp Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/mayaCommandHook.h Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/stringResources.h Show resolved Hide resolved
plugin/adsk/scripts/mayaUsdMenu.mel Outdated Show resolved Hide resolved
plugin/adsk/scripts/mayaUsdMenu.mel Show resolved Hide resolved
Copy link

@kxl-adsk kxl-adsk left a 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.

lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/layerEditorWidget.h Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/mayaCommandHook.cpp Outdated Show resolved Hide resolved
@@ -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):

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added more tests!

lib/mayaUsd/utils/util.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
lib/mayaUsd/nodes/layerManager.cpp Outdated Show resolved Hide resolved
return status;
}

MStatus setValueForAttr(const MObject& node, const MObject& attribute, const std::string& value)

Choose a reason for hiding this comment

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

Copy link
Contributor Author

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!

@alsoussi
Copy link
Contributor Author

@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.


// Share the stage
if (sharableStage) {
if (isIncomingStage) {
Copy link

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.

Copy link
Contributor Author

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);
Copy link

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?

Copy link
Contributor Author

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).

@@ -126,6 +129,8 @@ class MayaUsdProxyShapeBase
static MObject outStageDataAttr;
MAYAUSD_CORE_PUBLIC
static MObject outStageCacheIdAttr;
MAYAUSD_CORE_PUBLIC
static MObject outIsStageIncomingAttr;
Copy link

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.

Copy link
Contributor Author

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.


// 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;
Copy link

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.

Copy link
Contributor Author

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:

  1. Stage Data In port
  2. Stage Cache ID In Port
  3. File Path (Valid)
  4. 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

CHECK_MSTATUS_AND_RETURN_IT(retValue);
if (!remappedLayers.empty()) {
for (auto sublayer : sublayers) {
remapSublayerRecursive(sublayer, remappedLayers);
Copy link

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;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@alsoussi
Copy link
Contributor Author

alsoussi commented Jul 8, 2021

@kxl-adsk done!

Copy link

@kxl-adsk kxl-adsk left a comment

Choose a reason for hiding this comment

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

Thank you. LGTM.

Copy link
Collaborator

@seando-adsk seando-adsk left a 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.

lib/mayaUsd/utils/customLayerData.h Outdated Show resolved Hide resolved
lib/usd/ui/layerEditor/mayaCommandHook.cpp Outdated Show resolved Hide resolved
test/lib/CMakeLists.txt Outdated Show resolved Hide resolved
@@ -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)
Copy link
Collaborator

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"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@alsoussi
Copy link
Contributor Author

alsoussi commented Jul 8, 2021

@seando-adsk Done!

@kxl-adsk kxl-adsk merged commit 1646a8b into dev Jul 10, 2021
@kxl-adsk kxl-adsk deleted the t_al-sa/MAYA-112039/unsharable_stage branch July 10, 2021 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proxy Related to base proxy shape workflows Related to in-context workflows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants