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

Fix naming a prim to something that contains an invalid character crashes Maya #628

Merged
merged 4 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 6 additions & 0 deletions lib/mayaUsd/ufe/UsdUndoRenameCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ bool UsdUndoRenameCommand::renameRedo()
auto primPath = prim.GetPath();
auto defaultPrimPath = _stage->GetDefaultPrim().GetPath();

// all special characters are replaced with `_`
const std::string specialChars{"~!@#$%^&*()-=+,.?`':{}|<>[]/"};
std::replace_if(_newName.begin(), _newName.end(), [&](auto c){
return std::string::npos != specialChars.find(c);
}, '_');

// set prim's name
// XXX: SetName successfuly returns true but when you examine the _prim.GetName()
// after the rename, the prim name shows the original name HS, 6-May-2020.
Expand Down
48 changes: 48 additions & 0 deletions test/lib/ufe/testRename.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import mayaUsd.ufe

import unittest
import sys

class RenameTestCase(unittest.TestCase):
'''Test renaming a UFE scene item and its ancestors.
Expand Down Expand Up @@ -308,4 +309,51 @@ def testRenameRestrictionExternalReference(self):
newName = 'leaf_ref_2_renaming'
cmds.rename(newName)

def testRenameSpecialCharacter(self):
# open twoSpheres.ma scene in test-samples
mayaUtils.openTwoSpheresScene()

# clear selection to start off
cmds.select(clear=True)

# select a USD object.
mayaPathSegment = mayaUtils.createUfePathSegment('|world|usdSphereParent|usdSphereParentShape')
usdPathSegment = usdUtils.createUfePathSegment('/sphereXform/sphere')
basePath = ufe.Path([mayaPathSegment, usdPathSegment])
usdSphereItem = ufe.Hierarchy.createItem(basePath)

ufe.GlobalSelection.get().append(usdSphereItem)

# get the USD stage
stage = mayaUsd.ufe.getStage(str(mayaPathSegment))

# check GetLayerStack behavior
self.assertEqual(stage.GetLayerStack()[0], stage.GetSessionLayer())
self.assertEqual(stage.GetEditTarget().GetLayer(), stage.GetSessionLayer())

# set the edit target to the root layer
stage.SetEditTarget(stage.GetRootLayer())
self.assertEqual(stage.GetEditTarget().GetLayer(), stage.GetRootLayer())

# rename with special chars
newNameWithSpecialChars = '!@#%$@$=sph^e.re_*()<>}021|'
cmds.rename(newNameWithSpecialChars)

# the renamed item is in the selection.
snIter = iter(ufe.GlobalSelection.get())
pSphereItem = next(snIter)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since rename is UFE v2 only, you can just use Ufe::Selection::front():
pSphereItem = ufe.GlobalSelection.get().front()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ppt-adsk that's nice. Thanks for pointing out.

please see a036874

pSphereItemRenamed = str(pSphereItem.path().back())

# get the prim
usdPrim = stage.GetPrimAtPath('/sphereXform/' + pSphereItemRenamed)
Copy link
Collaborator

Choose a reason for hiding this comment

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

That would be just
usdPrim = stage.GetPrimAtPath(str(pSphereItem.path().segments[1]))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please see a036874

self.assertTrue(usdPrim)

# get the primspec
primspec = stage.GetEditTarget().GetPrimSpecForScenePath(usdPrim.GetPath());
self.assertTrue(primspec)

# rename
try:
primspec.name = pSphereItemRenamed
except:
print(sys.exc_info()[1])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not quite sure what this is testing in maya-usd. You are just testing USD primSpec renaming here, essentially, which should be tested in USD.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ppt-adsk I agree. this looks weird indeed. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ppt-adsk please see 2c89935