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-533 - Incremental naming doesn't take zero into consideration #3309

Merged

Conversation

seando-adsk
Copy link
Collaborator

EMSUSD-533 - Incremental naming doesn't take zero into consideration

  • Added optional DCC function for uniqueChildName() and override the UsdUfe one with Maya version: uniqueChildNameMayaStandard().
  • Split out numerical suffix handling in UsdUfe::uniqueName() into separate helper function.
  • When creating new unique name take into account length of numerical suffix (when padded with 0's).
  • Added new unit tests to testDuplicateCmd to test all these naming rules.

* Added optional DCC function for uniqueChildName() and override the
  UsdUfe one with Maya version: uniqueChildNameMayaStandard().
* Split out numerical suffix handling in UsdUfe::uniqueName() into
  separate helper function.
* When creating new unique name take into account length of numerical
  suffix (when padded with 0's).
* Added new unit tests to testDuplicateCmd to test all these naming rules.
@seando-adsk seando-adsk added the ufe-usd Related to UFE-USD plugin in Maya-Usd label Sep 5, 2023
@@ -164,6 +164,7 @@ MStatus initialize()
dccFunctions.timeAccessorFn = MayaUsd::ufe::getTime;
dccFunctions.isAttributeLockedFn = MayaUsd::Editability::isAttributeLocked;
dccFunctions.saveStageLoadRulesFn = MayaUsd::MayaUsdProxyShapeStageExtraData::saveLoadRules;
dccFunctions.uniqueChildNameFn = MayaUsd::ufe::uniqueChildNameMayaStandard;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From MayaUsd side, set optional uniqueChildName function to be used instead of the default one in UsdUfe.

Comment on lines +76 to +78
//! Returns a unique child name following the Maya standard naming rules.
MAYAUSD_CORE_PUBLIC
std::string uniqueChildNameMayaStandard(const PXR_NS::UsdPrim& usdParent, const std::string& name);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed the two inline mayaUsd versions of these functions (modified calling locations to use them from UsdUfe).

Added new mayaUsd verision of uniqueChildName that follows the Maya standard of naming.

: uniqueChildNameDefault(usdParent, name);
}

std::string uniqueChildNameDefault(const UsdPrim& usdParent, const std::string& name)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Left this function alone (other than adding "Default" to name). If you have children:

Capsule1
Capsule6

and you duplicate Capsule1 the new child will be Capsule2. This isn't how Maya naming works. Which is why I added the ability to override unqiueChildName function with your own.

@@ -278,27 +279,57 @@ int ufePathToInstanceIndex(const Ufe::Path& path, UsdPrim* prim)
return instanceIndex;
}

std::string uniqueName(const TfToken::HashSet& existingNames, std::string srcName)
bool splitNumericalSuffix(const std::string srcName, std::string& base, std::string& suffix)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Split out the first part of the original unqiueName function which separated the input name into base and numerical suffix. Made into helper so I can call it elsewhere.

Comment on lines +308 to +311
// Create a suffix string from the number keeping the same number of digits as
// numerical suffix from input srcName (padding with 0's if needed).
suffixStr = std::to_string(suffix);
suffixStr = std::string(lenSuffix - std::min(lenSuffix, suffixStr.length()), '0') + suffixStr;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Modified naming code here to maintain the 0 padded numerical suffix. So duplicating Capsule001 will give you Capsule002

// By sending in the largest matching name (instead of the input name)
// the unique name function will increment its numerical suffix by 1
// and thus it will be unique and follow Maya naming standard.
childName = uniqueName(allChildrenNames, largestMatching.first);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In this mayaUsd version I find only the greatest matching child (in the list of all children) and send that to the uniqueName function. In that way it will follow the Maya naming. So if you have:

Capsule001
Capsule006

and you duplicate Capsule001, the new child will be Capsule007

Comment on lines +650 to +652
def testDuplicateUniqueName(self):
'''Test the duplicate of prims and ensure the new name follows Maya
unique new name standard.'''
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Add a bunch of new test cases to verify my code changes for Usd prims, follow how Maya naming works.

Copy link
Collaborator

@pierrebai-adsk pierrebai-adsk left a comment

Choose a reason for hiding this comment

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

The while loop I flagged need to also add leading zeroes.

* Code review feedback - fixed case where zero padding was missing.
* Added python binding for 'uniqueName' and added new tests to
  cover case above.
* Added missing tests for python bindings.
lib/usdUfe/ufe/Utils.cpp Show resolved Hide resolved
@@ -104,11 +101,12 @@ void wrapUtils()
def("usdPathToUfePathSegment",
_usdPathToUfePathSegment,
(arg("usdPath"), arg("instanceIndex") = PXR_NS::UsdImagingDelegate::ALL_INSTANCES));
def("uniqueChildName", _uniqueChildName);
def("uniqueName", _uniqueName);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added missing python wrapper for this function.

@@ -104,11 +101,12 @@ void wrapUtils()
def("usdPathToUfePathSegment",
_usdPathToUfePathSegment,
(arg("usdPath"), arg("instanceIndex") = PXR_NS::UsdImagingDelegate::ALL_INSTANCES));
def("uniqueChildName", _uniqueChildName);
def("uniqueName", _uniqueName);
def("uniqueChildName", UsdUfe::uniqueChildName);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For some of these we don't need the extra _ helper defined here. Can just call the UsdUfe function directly.

test/lib/ufe/testPythonWrappers.py Show resolved Hide resolved
Comment on lines +89 to +91
# Test maya-usd usdPathToUfePathSegment wrapper.
ufePath = mayaUsd.ufe.usdPathToUfePathSegment('/Capsule1')
self.assertEqual(ufePath, str(usdUtils.createUfePathSegment('/Capsule1')))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added missing test for python wrapper.

Comment on lines +124 to +134
# stripInstanceIndexFromUfePath/ufePathToInstanceIndex wrappers are tested
# by testPointInstances.

# isEditTargetLayerModifiable wrapper is tested by testBlockedLayerEdit.

# Test the getTime wrapper.
cmds.currentTime(10)
t = mayaUsd.ufe.getTime(stagePath)
self.assertEqual(t, Usd.TimeCode(10))

# isAttributeEditAllowed wrapper is tested by testAttribute.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added missing test for python wrapper.

Comment on lines +136 to +150
# Test the maya-usd getPrimFromRawItem() wrapper.
capsulePath = proxyShapePath + usdUtils.createUfePathSegment('/Capsule1')
capsuleItem = ufe.Hierarchy.createItem(capsulePath)
rawItem = capsuleItem.getRawAddress()
capsulePrim2 = mayaUsd.ufe.getPrimFromRawItem(rawItem)
self.assertIsNotNone(capsulePrim2)
self.assertEqual(capsulePrim, capsulePrim2)

# Test the maya-usd getNodeTypeFromRawItem() wrapper.
nodeType = mayaUsd.ufe.getNodeTypeFromRawItem(rawItem)
self.assertIsNotNone(nodeType)

# Test the maya-usd getNodeNameFromRawItem() wrapper.
nodeName = mayaUsd.ufe.getNodeNameFromRawItem(rawItem)
self.assertIsNotNone(nodeName)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is code from before - I just removed the if ufe >=2

Comment on lines +97 to +122
newName = mayaUsd.ufe.uniqueName([], 'Capsule')
self.assertEqual(newName, 'Capsule1')
newName = mayaUsd.ufe.uniqueName([], 'Capsule1')
self.assertEqual(newName, 'Capsule2')
newName = mayaUsd.ufe.uniqueName(['Cone1'], 'Capsule1')
self.assertEqual(newName, 'Capsule2')
newName = mayaUsd.ufe.uniqueName(['Capsule1'], 'Capsule1')
self.assertEqual(newName, 'Capsule2')
newName = mayaUsd.ufe.uniqueName(['Capsule1', 'Capsule5'], 'Capsule1')
self.assertEqual(newName, 'Capsule2')
newName = mayaUsd.ufe.uniqueName(['Capsule001'], 'Capsule001')
self.assertEqual(newName, 'Capsule002')
newName = mayaUsd.ufe.uniqueName(['Capsule001', 'Capsule002'], 'Capsule001')
self.assertEqual(newName, 'Capsule003')
newName = mayaUsd.ufe.uniqueName(['Capsule001', 'Capsule005'], 'Capsule001')
self.assertEqual(newName, 'Capsule002')

# Test uniqueChildName wrapper.
newName = mayaUsd.ufe.uniqueChildName(capsulePrim, 'Cone1')
self.assertEqual(newName, 'Cone1')
mayaUsdStage.DefinePrim("/Capsule1/Cone1", "Cone")
newName = mayaUsd.ufe.uniqueChildName(capsulePrim, 'Cone1')
self.assertEqual(newName, 'Cone2')
mayaUsdStage.DefinePrim("/Capsule1/Sphere001", "Sphere")
newName = mayaUsd.ufe.uniqueChildName(capsulePrim, 'Sphere001')
self.assertEqual(newName, 'Sphere002')
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

New tests to cover uniqueName/uniqueChildName, especially the missing numerical padding case you caught with my original code.

pierrebai-adsk
pierrebai-adsk previously approved these changes Sep 6, 2023
pierrebai-adsk
pierrebai-adsk previously approved these changes Sep 6, 2023
* Fix Linux/Mac build issues and broken unit tests.
* Add variable initialization to fix random problem. The iteration
  order of TfToken::HashSet is not guaranteed because the hash is
  by memory address.
@seando-adsk
Copy link
Collaborator Author

@pierrebai-adsk Sorry had some trouble with Linux/Mac builds and the unit test. Had to make some extra fixes.

@seando-adsk seando-adsk added the ready-for-merge Development process is finished, PR is ready for merge label Sep 11, 2023
@seando-adsk seando-adsk merged commit 3f5039c into dev Sep 11, 2023
10 checks passed
@seando-adsk seando-adsk deleted the donnels/EMSUSD-533/incremental_naming_with_zero_padding branch September 11, 2023 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-merge Development process is finished, PR is ready for merge ufe-usd Related to UFE-USD plugin in Maya-Usd
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants