Skip to content

Commit

Permalink
Merge pull request #2523 from Autodesk/t_bailp/MAYA-MAYA-108733/remov…
Browse files Browse the repository at this point in the history
…e-multiple-usd-layers

MAYA-108733 fix removing multiple layers at the same time
  • Loading branch information
seando-adsk authored Sep 2, 2022
2 parents 32aa67a + 1030bfa commit 2e54853
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 7 deletions.
75 changes: 69 additions & 6 deletions lib/mayaUsd/commands/layerEditorCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,59 @@ class MuteLayer : public BaseCmd
PXR_NS::SdfLayerRefPtr _mutedLayer;
};

// We assume the indexes given to the command are the original indexes
// of the layers. Since each command is executed individually and in
// order, each one may affect the index of subsequent commands. We
// records adjustements that must be applied to indexes in the map.
// Removal of a layer creates a negative adjustment, insertion of a
// layer creates a positive adjustment.
class IndexAdjustments
{
public:
IndexAdjustments() = default;

// Convenience method that retrieve the adjusted index and adds
// the insertion index adjustment.
int insertionAdjustment(int originalIndex)
{
const int adjustedIndex = getAdjustedIndex(originalIndex);
addInsertionAdjustment(originalIndex);
return adjustedIndex;
}

// Convenience method that retrieve the adjusted index and adds
// the removal index adjustment.
int removalAdjustment(int originalIndex)
{
const int adjustedIndex = getAdjustedIndex(originalIndex);
addRemovalAdjustment(originalIndex);
return adjustedIndex;
}

private:
// Insertion and removal additional adjustment.
// Must be called with the original index as provided by the user.
void addInsertionAdjustment(int index) { _indexAdjustments[index] += 1; }
void addRemovalAdjustment(int index) { _indexAdjustments[index] -= 1; }

// Calculate the adjusted index from the user-supplied index that
// need to be used by the command to account for previous commands.
int getAdjustedIndex(int index) const
{
// Apply all adjustment that were done on indexes lower or
// equal to the input index.
int adjustedIndex = index;
for (const auto& indexAndAdjustement : _indexAdjustments) {
if (indexAndAdjustement.first > index)
break;
adjustedIndex += indexAndAdjustement.second;
}
return adjustedIndex;
}

std::map<int, int> _indexAdjustments;
};

} // namespace Impl

const char LayerEditorCommand::commandName[] = "mayaUsdLayerEditor";
Expand Down Expand Up @@ -694,15 +747,22 @@ MStatus LayerEditorCommand::parseArgs(const MArgList& argList)
_layerIdentifier = objects[0].asChar();

if (!isQuery()) {
Impl::IndexAdjustments indexAdjustments;

if (argParser.isFlagSet(kInsertSubPathFlag)) {
auto count = argParser.numberOfFlagUses(kInsertSubPathFlag);
for (unsigned i = 0; i < count; i++) {
auto cmd = std::make_shared<Impl::InsertSubPath>();

MArgList listOfArgs;
argParser.getFlagArgumentList(kInsertSubPathFlag, i, listOfArgs);
cmd->_index = listOfArgs.asInt(0);

const int originalIndex = listOfArgs.asInt(0);
const int adjustedIndex = indexAdjustments.insertionAdjustment(originalIndex);

cmd->_index = adjustedIndex;
cmd->_subPath = listOfArgs.asString(1).asUTF8();

_subCommands.push_back(std::move(cmd));
}
}
Expand All @@ -714,16 +774,18 @@ MStatus LayerEditorCommand::parseArgs(const MArgList& argList)
MArgList listOfArgs;
argParser.getFlagArgumentList(kRemoveSubPathFlag, i, listOfArgs);

auto index = listOfArgs.asInt(0);
auto shapePath = listOfArgs.asString(1);
auto prim = UsdMayaQuery::GetPrim(shapePath.asChar());
if (prim == UsdPrim()) {
displayError(MString("Invalid proxy shape \"") + shapePath.asChar() + "\"");
return MS::kInvalidParameter;
}

const int originalIndex = listOfArgs.asInt(0);
const int adjustedIndex = indexAdjustments.removalAdjustment(originalIndex);

auto cmd = std::make_shared<Impl::RemoveSubPath>();
cmd->_index = index;
cmd->_index = adjustedIndex;
cmd->_proxyShapePath = shapePath.asChar();
_subCommands.push_back(std::move(cmd));
}
Expand All @@ -749,11 +811,12 @@ MStatus LayerEditorCommand::parseArgs(const MArgList& argList)
MString newParentLayer;
argParser.getFlagArgument(kMoveSubPathFlag, 1, newParentLayer);

unsigned int index { 0 };
argParser.getFlagArgument(kMoveSubPathFlag, 2, index);
int originalIndex { 0 };
argParser.getFlagArgument(kMoveSubPathFlag, 2, originalIndex);
const int adjustedIndex = indexAdjustments.removalAdjustment(originalIndex);

auto cmd = std::make_shared<Impl::MoveSubPath>(
subPath.asUTF8(), newParentLayer.asUTF8(), index);
subPath.asUTF8(), newParentLayer.asUTF8(), adjustedIndex);
_subCommands.push_back(std::move(cmd));
}

Expand Down
34 changes: 33 additions & 1 deletion test/lib/testMayaUsdLayerEditorCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import unittest
import tempfile
from os import path
from maya import cmds
from maya import cmds, mel
import mayaUsd_createStageWithNewLayer
import mayaUsd
from pxr import Sdf, Usd
Expand Down Expand Up @@ -362,6 +362,38 @@ def setAndRemoveEditTargetRecursive(layer, index, editLayer):
cmds.undo()
self.assertEqual(path.normcase(stage.GetEditTarget().GetLayer().identifier), sharedLayer)

def testRemoveMultipleLayers(self):

shapePath, stage = getCleanMayaStage()
rootLayer = stage.GetRootLayer()
rootLayerID = rootLayer.identifier

# Add six layers
layerNames = []
for index in range(1,7):
layerName = "layer%d" % index
layerName = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=True, addAnonymous=layerName)
layerNames.append(layerName[0])

# Verify that the root has the expected six layers.
def subLayerNames():
return list(rootLayer.subLayerPaths)

def verifySubLayers(expectedNames):
rootSubLayers = subLayerNames()
self.assertEqual(len(expectedNames), len(rootSubLayers))
for name in expectedNames:
self.assertIn(name, rootSubLayers)

verifySubLayers(layerNames)

# Remove layers 0 and 1 and verify that the correct layers have been removed.
#
# Note: when inserted in USD, layers are added at the top, so layer 0 and 1 are
# layer5 and layer6.
cmds.mayaUsdLayerEditor(rootLayer.identifier, removeSubPath=((0, shapePath), (1, shapePath)))
verifySubLayers(layerNames[0:4])

def testMoveSubPath(self):
""" test 'mayaUsdLayerEditor' command 'moveSubPath' paramater """

Expand Down

0 comments on commit 2e54853

Please sign in to comment.