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

EMSUSD-885 - Targets the session layer when no other layers are modifiable #3665

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions lib/mayaUsd/commands/layerEditorCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class BaseCmd
void holdOntoSubLayers(SdfLayerHandle layer);
void releaseSubLayers() { _subLayersRefs.clear(); }
void holdOnPathIfDirty(SdfLayerHandle layer, std::string path);
void updateEditTarget(const PXR_NS::UsdStageWeakPtr stage);
};

void BaseCmd::holdOnPathIfDirty(SdfLayerHandle layer, std::string path)
Expand All @@ -129,6 +130,23 @@ void BaseCmd::holdOntoSubLayers(SdfLayerHandle layer)
}
}

// Set the edit target to Session layer if no other layers are modifiable
void BaseCmd::updateEditTarget(const PXR_NS::UsdStageWeakPtr stage)
{
if (!stage)
return;

if (stage->GetEditTarget().GetLayer() == stage->GetSessionLayer())
return;

// If there are no target-able layers, we set the target to session layer.
std::string errMsg;
if (!UsdUfe::isAnyLayerModifiable(stage, &errMsg)) {
MPxCommand::displayInfo(errMsg.c_str());
stage->SetEditTarget(stage->GetSessionLayer());
}
}

class InsertRemoveSubPathBase : public BaseCmd
{
public:
Expand Down Expand Up @@ -718,6 +736,9 @@ class MuteLayer : public BaseCmd
// to the muted layer. OpenUSD let go of muted layers, so anonymous
// layers and any dirty children would be lost if not explicitly held on.
addMutedLayer(layer);

updateEditTarget(stage);

return true;
}

Expand All @@ -738,6 +759,9 @@ class MuteLayer : public BaseCmd

// We can release the now unmuted layers.
removeMutedLayer(layer);

updateEditTarget(stage);

return true;
}

Expand Down Expand Up @@ -826,6 +850,8 @@ class LockLayer : public BaseCmd
MayaUsd::lockLayer(_proxyShapePath, _layers[layerIndex], _lockType, true);
}

updateEditTarget(stage);

return true;
}

Expand Down Expand Up @@ -854,6 +880,8 @@ class LockLayer : public BaseCmd
}
restoreSelection();

updateEditTarget(stage);

return true;
}

Expand Down Expand Up @@ -937,19 +965,28 @@ class RefreshSystemLockLayer : public BaseCmd
}
}

updateEditTarget(stage);

return true;
}

// The command itself doesn't retain its state. However, the underlying logic contains commands
// that are undoable.
bool undoIt(SdfLayerHandle layer) override
{
auto stage = getStage();
if (!stage)
return false;

// Execute lock commands
for (size_t layerIndex = 0; layerIndex < _layers.size(); layerIndex++) {
if (!_lockCommands[layerIndex]->undoIt(_layers[layerIndex])) {
return false;
}
}

updateEditTarget(stage);

return true;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/usdUfe/python/wrapUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ int _ufePathToInstanceIndex(const std::string& ufePathString)
return UsdUfe::ufePathToInstanceIndex(Ufe::PathString::path(ufePathString));
}

bool _isAnyLayerModifiable(const PXR_NS::UsdStageWeakPtr stage)
{
return UsdUfe::isAnyLayerModifiable(stage);
}

bool _isEditTargetLayerModifiable(const PXR_NS::UsdStageWeakPtr stage)
{
return UsdUfe::isEditTargetLayerModifiable(stage);
Expand Down Expand Up @@ -114,6 +119,7 @@ void wrapUtils()
def("stripInstanceIndexFromUfePath", _stripInstanceIndexFromUfePath, (arg("ufePathString")));
def("ufePathToPrim", _ufePathToPrim);
def("ufePathToInstanceIndex", _ufePathToInstanceIndex);
def("isAnyLayerModifiable", _isAnyLayerModifiable);
def("isEditTargetLayerModifiable", _isEditTargetLayerModifiable);
def("getTime", _getTime);
def("isAttributeEditAllowed", _isAttributeEditAllowed);
Expand Down
21 changes: 21 additions & 0 deletions lib/usdUfe/ufe/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,27 @@ void enforceAttributeEditAllowed(const UsdPrim& prim, const TfToken& attrName)
}
}

bool isAnyLayerModifiable(const UsdStageWeakPtr stage, std::string* errMsg /* = nullptr */)
{
PXR_NS::SdfLayerHandleVector layers = stage->GetLayerStack(false);
for (auto layer : layers) {
if (!layer->IsMuted() && layer->PermissionToEdit()) {
return true;
}
}

if (errMsg) {
std::string err = TfStringPrintf(
"Cannot target any layers in the stage [%s] because the layers are either locked or "
"muted. Switching to session layer.",
stage->GetRootLayer()->GetIdentifier().c_str());

*errMsg = err;
}

return false;
}

bool isEditTargetLayerModifiable(const UsdStageWeakPtr stage, std::string* errMsg)
{
const auto editTarget = stage->GetEditTarget();
Expand Down
5 changes: 5 additions & 0 deletions lib/usdUfe/ufe/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,11 @@ void applyRootLayerMetadataRestriction(
const PXR_NS::UsdStageRefPtr& stage,
const std::string& commandName);

//! Check if any layers in the stage is allowed to be changed.
//! \return True, if at least one layer in the stage is allowed to be changed
USDUFE_PUBLIC
bool isAnyLayerModifiable(const PXR_NS::UsdStageWeakPtr stage, std::string* errMsg = nullptr);

//! Check if the edit target in the stage is allowed to be changed.
//! \return True, if the edit target layer in the stage is allowed to be changed
USDUFE_PUBLIC
Expand Down
8 changes: 7 additions & 1 deletion test/lib/testMayaUsdLayerEditorCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from maya import cmds, mel
import mayaUsd_createStageWithNewLayer
import mayaUsd
from mayaUsd import ufe as mayaUsdUfe

from pxr import Sdf, Usd

CLEAR = "-clear"
Expand Down Expand Up @@ -593,10 +595,14 @@ def testLayerLockWritePermission(self):
# 3- Check that sublayer is also locked
subLayer = Sdf.Layer.FindRelativeToLayer(topLayer, topLayer.subLayerPaths[0])
self.assertFalse(subLayer.permissionToEdit)
# 4- Undo and check that both top and sublayer are unlocked
# 4- Checking that no layers are modifiable
self.assertFalse(mayaUsdUfe.isAnyLayerModifiable(stage))
# 5- Undo and check that both top and sublayer are unlocked
cmds.undo()
self.assertTrue(topLayer.permissionToEdit)
self.assertTrue(subLayer.permissionToEdit)
# 6- Checking that at least one layer is modifiable
self.assertTrue(mayaUsdUfe.isAnyLayerModifiable(stage))

def testMuteLayer(self):
""" test 'mayaUsdLayerEditor' command 'muteLayer' paramater """
Expand Down