Skip to content

Commit

Permalink
Merge pull request #2109 from Autodesk/tremblp/MAYA-114726/duplicate_…
Browse files Browse the repository at this point in the history
…set_selection

mayaUsdDuplicate selects duplicated object.
  • Loading branch information
seando-adsk authored Feb 16, 2022
2 parents cf5f97a + dac6127 commit 4ef328b
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 1 deletion.
23 changes: 23 additions & 0 deletions lib/mayaUsd/commands/PullPushCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@
#include <mayaUsd/fileio/jobs/jobArgs.h>
#include <mayaUsd/fileio/primUpdaterManager.h>
#include <mayaUsd/fileio/shading/shadingModeRegistry.h>
#include <mayaUsd/ufe/Global.h>
#include <mayaUsd/ufe/Utils.h>
#include <mayaUsd/undo/OpUndoItemRecorder.h>
#include <mayaUsd/undo/OpUndoItems.h>
#include <mayaUsd/utils/util.h>

#include <maya/MArgParser.h>
#include <maya/MGlobal.h>
#include <maya/MStringArray.h>
#include <maya/MSyntax.h>
#include <ufe/hierarchy.h>
#include <ufe/path.h>
#include <ufe/pathString.h>
#include <ufe/selection.h>

#include <algorithm>

Expand Down Expand Up @@ -404,6 +408,25 @@ MStatus DuplicateCommand::doIt(const MArgList& argList)

auto& manager = PXR_NS::PrimUpdaterManager::getInstance();
status = manager.duplicate(fSrcPath, fDstPath, userArgs) ? MS::kSuccess : MS::kFailure;

// If the duplicate src is Maya, the duplicate child of the destination
// will be USD, and vice-versa. Construct an appropriate child path:
// - Maya duplicate to USD: we always duplicate directly under the
// proxy shape, so add a single path component USD path segment.
// - USD duplicate to Maya: no path segment to add.
Ufe::Path childPath = (fSrcPath.runTimeId() == getMayaRunTimeId())
?
// Maya duplicate to USD
fDstPath + Ufe::PathSegment(fSrcPath.back(), getUsdRunTimeId(), '/')
// USD duplicate to Maya
: fDstPath + fSrcPath.back();

Ufe::Selection sn;
sn.append(Ufe::Hierarchy::createItem(childPath));
// It is appropriate to use the overload that uses the global list, as
// the undo recorder will transfer the items on the global list to
// fUndoItemList.
UfeSelectionUndoItem::select("duplicate", sn);
}

// Undo potentially partially-made duplicate on failure.
Expand Down
55 changes: 54 additions & 1 deletion lib/mayaUsd/undo/OpUndoItems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include <maya/MGlobal.h>
#include <maya/MItDag.h>
#include <maya/MSelectionList.h>
#ifdef WANT_UFE_BUILD
#include <ufe/globalSelection.h>
#include <ufe/observableSelection.h>
#endif

namespace MAYAUSD_NS_DEF {

Expand Down Expand Up @@ -355,6 +359,55 @@ bool SelectionUndoItem::redo()
return status == MS::kSuccess;
}

#ifdef WANT_UFE_BUILD
//------------------------------------------------------------------------------
// UfeSelectionUndoItem
//------------------------------------------------------------------------------

UfeSelectionUndoItem::UfeSelectionUndoItem(const std::string& name, const Ufe::Selection& selection)
: OpUndoItem(name)
, _selection(selection)
{
}

UfeSelectionUndoItem::~UfeSelectionUndoItem() { }

void UfeSelectionUndoItem::select(
const std::string& name,
const Ufe::Selection& selection,
OpUndoItemList& undoInfo)
{
auto item = std::make_unique<UfeSelectionUndoItem>(name, selection);
item->redo();
undoInfo.addItem(std::move(item));
}

void UfeSelectionUndoItem::select(const std::string& name, const Ufe::Selection& selection)
{
select(name, selection, OpUndoItemList::instance());
}

bool UfeSelectionUndoItem::undo()
{
invert();
return true;
}

bool UfeSelectionUndoItem::redo()
{
invert();
return true;
}

void UfeSelectionUndoItem::invert()
{
auto globalSn = Ufe::GlobalSelection::get();
auto previousSelection = *globalSn;
globalSn->replaceWith(_selection);
_selection = std::move(previousSelection);
}
#endif

//------------------------------------------------------------------------------
// LockNodesUndoItem
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -472,4 +525,4 @@ bool CreateSetUndoItem::redo()
return status == MS::kSuccess;
}

} // namespace MAYAUSD_NS_DEF
} // namespace MAYAUSD_NS_DEF
45 changes: 45 additions & 0 deletions lib/mayaUsd/undo/OpUndoItems.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <maya/MFnSet.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
#ifdef WANT_UFE_BUILD
#include <ufe/selection.h>
#endif

#include <memory>
#include <vector>
Expand Down Expand Up @@ -403,6 +406,48 @@ class SelectionUndoItem : public OpUndoItem
MGlobal::ListAdjustment _selMode;
};

#ifdef WANT_UFE_BUILD
//------------------------------------------------------------------------------
// UfeSelectionUndoItem
//------------------------------------------------------------------------------

/// \class UfeSelectionUndoItem
/// \brief Record data needed to undo or redo select nodes sub-operations.
class UfeSelectionUndoItem : public OpUndoItem
{
public:
/// \brief Create and execute a select node undo item and keep track of it. The global
/// selection is replaced.
MAYAUSD_CORE_PUBLIC
static void
select(const std::string& name, const Ufe::Selection& selection, OpUndoItemList& undoInfo);

/// \brief create and execute a select node undo item and keep track of it in the global list.
/// The global selection is replaced.
MAYAUSD_CORE_PUBLIC
static void select(const std::string& name, const Ufe::Selection& selection);

MAYAUSD_CORE_PUBLIC
UfeSelectionUndoItem(const std::string& name, const Ufe::Selection& selection);

MAYAUSD_CORE_PUBLIC
~UfeSelectionUndoItem() override;

/// \brief undo a single sub-operation.
MAYAUSD_CORE_PUBLIC
bool undo() override;

/// \brief redo a single sub-operation.
MAYAUSD_CORE_PUBLIC
bool redo() override;

private:
void invert();

Ufe::Selection _selection;
};
#endif

//------------------------------------------------------------------------------
// LockNodesUndoItem
//------------------------------------------------------------------------------
Expand Down
18 changes: 18 additions & 0 deletions test/lib/mayaUsd/fileio/testDuplicateAs.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ def testDuplicateAsMayaUndoRedo(self):
bXlation, bUsdUfePathStr, bUsdUfePath, _) = \
createSimpleXformScene()

# Capture selection before duplicate.
previousSn = cmds.ls(sl=True, ufe=True, long=True)

# Duplicate USD data as Maya data, placing it under the root.
cmds.mayaUsdDuplicate(aUsdUfePathStr, '|world')

Expand All @@ -111,13 +114,19 @@ def verifyDuplicate():
self.assertEqual(cmds.getAttr(bMayaPathStr + '.translate')[0],
bXlation)

# Selection is on the duplicate.
sn = cmds.ls(sl=True, ufe=True, long=True)
self.assertEqual(len(sn), 1)
self.assertEqual(sn[0], aMayaPathStr)

verifyDuplicate()

cmds.undo()

def verifyDuplicateIsGone():
bMayaPathStr = str(bUsdUfePath.segments[1]).replace('/', '|')
self.assertListEqual(cmds.ls(bMayaPathStr, long=True), [])
self.assertEqual(cmds.ls(sl=True, ufe=True, long=True), previousSn)

verifyDuplicateIsGone()

Expand Down Expand Up @@ -211,6 +220,9 @@ def testDuplicateAsUsdUndoRedo(self):
# Create a stage to receive the USD duplicate.
psPathStr = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()

# Capture selection before duplicate.
previousSn = cmds.ls(sl=True, ufe=True, long=True)

# Duplicate Maya data as USD data. As of 17-Nov-2021 no single-segment
# path handler registered to UFE for Maya path strings, so use absolute
# path.
Expand Down Expand Up @@ -238,6 +250,11 @@ def verifyDuplicate():
self.assertEqual([1, 2, 3], usdGroup1T3d.translation().vector)
self.assertEqual([-4, -5, -6], usdGroup2T3d.translation().vector)

# Selection is on duplicate.
sn = cmds.ls(sl=True, ufe=True, long=True)
self.assertEqual(len(sn), 1)
self.assertEqual(sn[0], usdGroup2PathStr)

verifyDuplicate()

cmds.undo()
Expand All @@ -248,6 +265,7 @@ def verifyDuplicateIsGone():
usdGroup2Path = ufe.PathString.path(usdGroup2PathStr)
usdGroup2 = ufe.Hierarchy.createItem(usdGroup2Path)
self.assertIsNone(usdGroup2)
self.assertEqual(cmds.ls(sl=True, ufe=True, long=True), previousSn)

verifyDuplicateIsGone()

Expand Down

0 comments on commit 4ef328b

Please sign in to comment.