def testManipulatePointInstancePosition(self): # Create a UFE path to a PointInstancer prim with an instanceIndex on # the end. This path uniquely identifies a specific point instance. # We also pick one with a non-zero initial position. instanceIndex = 7 ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment( '/PointInstancerGrid/PointInstancer/%d' % instanceIndex) ]) ufeItem = ufe.Hierarchy.createItem(ufePath) # Select the point instance scene item. globalSelection = ufe.GlobalSelection.get() globalSelection.append(ufeItem) # Get the PointInstancer prim for validating the values in USD. ufePathString = ufe.PathString.string(ufePath) prim = mayaUsdUfe.ufePathToPrim(ufePathString) pointInstancer = UsdGeom.PointInstancer(prim) self.assertTrue(pointInstancer) # The PointInstancer should have 14 authored positions initially. positionsAttr = pointInstancer.GetPositionsAttr() positions = positionsAttr.Get() self.assertEqual(len(positions), 14) # Validate the initial position before manipulating position = positions[instanceIndex] self.assertTrue( Gf.IsClose(position, Gf.Vec3f(-4.5, 1.5, 0.0), self.EPSILON)) # Perfom a translate manipulation via the move command. cmds.move(1.0, 2.0, 3.0, objectSpace=True, relative=True) # Re-fetch the USD positions and check for the update. position = positionsAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(position, Gf.Vec3f(-3.5, 3.5, 3.0), self.EPSILON)) # Try another move. cmds.move(6.0, 5.0, 4.0, objectSpace=True, relative=True) # Re-fetch the USD positions and check for the update. position = positionsAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(position, Gf.Vec3f(2.5, 8.5, 7.0), self.EPSILON)) # Now undo, and re-check. cmds.undo() position = positionsAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(position, Gf.Vec3f(-3.5, 3.5, 3.0), self.EPSILON)) # And once more. cmds.undo() position = positionsAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(position, Gf.Vec3f(-4.5, 1.5, 0.0), self.EPSILON))
def __init__(self, ufeSceneItem): self.item = ufeSceneItem self.prim = mayaUsdUfe.ufePathToPrim( ufe.PathString.string(self.item.path())) # Get the UFE Attributes interface for this scene item. self.attrS = ufe.Attributes.attributes(self.item) self.suppressedAttrs = [] self.showArrayAttributes = False if cmds.optionVar(exists="mayaUSD_AEShowArrayAttributes"): self.showArrayAttributes = cmds.optionVar( query="mayaUSD_AEShowArrayAttributes") cmds.editorTemplate(beginScrollLayout=True) self.buildUI() cmds.editorTemplate(addExtraControls=True) self.createMetadataSection() cmds.editorTemplate(endScrollLayout=True)
def testImportModule(self): from mayaUsd import ufe as mayaUsdUfe import ufe # Test calling a function that depends on USD. This exercises the # script module loader registry function and ensures that loading the # ufe library also loaded its dependencies (i.e. the core USD # libraries). We test the type name as a string to ensure that we're # not causing USD libraries to be loaded any other way. if ufe.VersionInfo.getMajorVersion() == 1: # In UFE v1 if the Nb segments == 1, returns invalid prim invalidPrim = mayaUsdUfe.ufePathToPrim('a') else: # raw item only introduced in UFE v2 invalidPrim = mayaUsdUfe.getPrimFromRawItem(0) # Prior to USD version 20.05, a default constructed UsdPrim() in C++ # would be returned to Python as a Usd.Object rather than a Usd.Prim. # Since we still want to support earlier versions, make sure it's one # of the two. typeName = type(invalidPrim).__name__ self.assertIn(typeName, ['Prim', 'Object'])
def __init__(self, ufeSceneItem): self.item = ufeSceneItem self.prim = mayaUsdUfe.ufePathToPrim( ufe.PathString.string(self.item.path())) # Get the UFE Attributes interface for this scene item. self.attrS = ufe.Attributes.attributes(self.item) self.addedAttrs = [] self.suppressedAttrs = [] self.showArrayAttributes = False if cmds.optionVar(exists="mayaUSD_AEShowArrayAttributes"): self.showArrayAttributes = cmds.optionVar( query="mayaUSD_AEShowArrayAttributes") # Should we display nice names in AE? self.useNiceName = True if cmds.optionVar(exists='attrEditorIsLongName'): self.useNiceName = (cmds.optionVar(q='attrEditorIsLongName') == 1) cmds.editorTemplate(beginScrollLayout=True) self.buildUI() self.createAppliedSchemasSection() self.createCustomExtraAttrs() self.createMetadataSection() cmds.editorTemplate(endScrollLayout=True) if ('%s.%s' % (cmds.about(majorVersion=True), cmds.about(minorVersion=True))) > '2022.1': # Because of how we dynamically build the Transform attribute section, # we need this template to rebuild each time it is needed. This will # also restore the collapse/expand state of the sections. # Note: in Maya 2022 all UFE templates were forcefully rebuilt, but # no restore of section states. try: cmds.editorTemplate(forceRebuild=True) except: pass
def testPointInstances(self): # Create a UFE path to a PointInstancer prim with an instanceIndex on # the end. This path uniquely identifies a specific point instance. ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment( '/PointInstancerGrid/PointInstancer/7') ]) ufeItem = ufe.Hierarchy.createItem(ufePath) # Verify that we turned the path into a scene item correctly and that # we can access the PointInstancer prim. self.assertEqual(ufeItem.nodeType(), 'PointInstancer') ufeAttrs = ufe.Attributes.attributes(ufeItem) self.assertTrue(ufeAttrs.hasAttribute(UsdGeom.Tokens.positions)) # XXX: Note that UsdSceneItem currently has no wrapping to Python, so # we are not able to verify that we can query the scene item directly # for its instance index. We can exercise the Utils functions though. ufePathString = ufe.PathString.string(ufePath) prim = mayaUsdUfe.ufePathToPrim(ufePathString) self.assertTrue(prim) self.assertTrue(prim.IsA(UsdGeom.PointInstancer)) instanceIndex = mayaUsdUfe.ufePathToInstanceIndex(ufePathString) self.assertEqual(instanceIndex, 7) # Tests for the usdPathToUfePathSegment() utility function. ufePathSegmentString = mayaUsdUfe.usdPathToUfePathSegment( prim.GetPrimPath()) self.assertEqual(ufePathSegmentString, '/PointInstancerGrid/PointInstancer') ufePathSegmentString = mayaUsdUfe.usdPathToUfePathSegment( prim.GetPrimPath(), 7) self.assertEqual(ufePathSegmentString, '/PointInstancerGrid/PointInstancer/7') ufePrimPathString = mayaUsdUfe.stripInstanceIndexFromUfePath( ufePathString) self.assertEqual( ufePrimPathString, '|UsdProxy|UsdProxyShape,/PointInstancerGrid/PointInstancer') # Create a path to the PointInstancer itself and verify that the # instanceIndex is ALL_INSTANCES. # XXX: Ideally we would use a named constant provided by # UsdImagingDelegate for ALL_INSTANCES, but currently that library does # not have any Python wrapping. We *could* get it indirectly as # UsdImagingGL.ALL_INSTANCES, but that would bring unnecessary baggage # with it, so we just re-define it here. ALL_INSTANCES = -1 ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment('/PointInstancerGrid/PointInstancer') ]) ufePathString = ufe.PathString.string(ufePath) instanceIndex = mayaUsdUfe.ufePathToInstanceIndex(ufePathString) self.assertEqual(instanceIndex, ALL_INSTANCES) # Create a path to a non-PointInstancer prim but append an instance # index to it. This isn't really a valid path, but the utility function # should recognize this case and return an instanceIndex of # ALL_INSTANCES. ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment('/PointInstancerGrid/7') ]) ufePathString = ufe.PathString.string(ufePath) instanceIndex = mayaUsdUfe.ufePathToInstanceIndex(ufePathString) self.assertEqual(instanceIndex, ALL_INSTANCES)
def testManipulatePointInstanceScale(self): # Create a UFE path to a PointInstancer prim with an instanceIndex on # the end. This path uniquely identifies a specific point instance. instanceIndex = 7 ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment( '/PointInstancerGrid/PointInstancer/%d' % instanceIndex) ]) ufeItem = ufe.Hierarchy.createItem(ufePath) # Select the point instance scene item. globalSelection = ufe.GlobalSelection.get() globalSelection.append(ufeItem) # Get the PointInstancer prim for validating the values in USD. ufePathString = ufe.PathString.string(ufePath) prim = mayaUsdUfe.ufePathToPrim(ufePathString) pointInstancer = UsdGeom.PointInstancer(prim) self.assertTrue(pointInstancer) # The PointInstancer should not have any authored scales initially. scalesAttr = pointInstancer.GetScalesAttr() self.assertFalse(scalesAttr.HasAuthoredValue()) # Perfom a scale manipulation via the scale command. cmds.scale(1.0, 2.0, 3.0, objectSpace=True, relative=True) # The initial scale should have filled out the scales attribute. scales = scalesAttr.Get() self.assertEqual(len(scales), 14) # Validate the scaled item. scale = scales[instanceIndex] self.assertTrue( Gf.IsClose(scale, Gf.Vec3f(1.0, 2.0, 3.0), self.EPSILON)) # The non-scaled items should all have identity scales. for i in [idx for idx in range(14) if idx != instanceIndex]: scale = scales[i] self.assertTrue( Gf.IsClose(scale, Gf.Vec3f(1.0, 1.0, 1.0), self.EPSILON)) # Perfom another scale. cmds.scale(4.0, 5.0, 6.0, objectSpace=True, relative=True) # Re-fetch the USD scale and check for the update. scale = scalesAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(scale, Gf.Vec3f(4.0, 10.0, 18.0), self.EPSILON)) # Now undo, and re-check. cmds.undo() scale = scalesAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(scale, Gf.Vec3f(1.0, 2.0, 3.0), self.EPSILON)) # And once more. # Note that with more complete undo support, this would ideally clear # the authored scales attribute, returning it to its true original # state. For now, we just validate that the scale value is back to its # default of identity. cmds.undo() scale = scalesAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(scale, Gf.Vec3f(1.0, 1.0, 1.0), self.EPSILON))
def testManipulatePointInstanceOrientation(self): # Create a UFE path to a PointInstancer prim with an instanceIndex on # the end. This path uniquely identifies a specific point instance. instanceIndex = 7 ufePath = ufe.Path([ mayaUtils.createUfePathSegment('|UsdProxy|UsdProxyShape'), usdUtils.createUfePathSegment( '/PointInstancerGrid/PointInstancer/%d' % instanceIndex) ]) ufeItem = ufe.Hierarchy.createItem(ufePath) # Select the point instance scene item. globalSelection = ufe.GlobalSelection.get() globalSelection.append(ufeItem) # Get the PointInstancer prim for validating the values in USD. ufePathString = ufe.PathString.string(ufePath) prim = mayaUsdUfe.ufePathToPrim(ufePathString) pointInstancer = UsdGeom.PointInstancer(prim) self.assertTrue(pointInstancer) # The PointInstancer should not have any authored orientations # initially. orientationsAttr = pointInstancer.GetOrientationsAttr() self.assertFalse(orientationsAttr.HasAuthoredValue()) # Perfom an orientation manipulation via the rotate command. cmds.rotate(15.0, 30.0, 45.0, objectSpace=True, relative=True) # The initial rotate should have filled out the orientations attribute. orientations = orientationsAttr.Get() self.assertEqual(len(orientations), 14) # Validate the rotated item. orientation = orientations[instanceIndex] self.assertTrue(Gf.IsClose(orientation.real, 0.897461, self.EPSILON)) self.assertTrue( Gf.IsClose(orientation.imaginary, Gf.Vec3h(0.01828, 0.2854, 0.335205), self.EPSILON)) # The non-rotated items should all have identity orientations. for i in [idx for idx in range(14) if idx != instanceIndex]: orientation = orientations[i] self.assertTrue( Gf.IsClose(orientation.real, Gf.Quath.GetIdentity().real, self.EPSILON)) self.assertTrue( Gf.IsClose(orientation.imaginary, Gf.Quath.GetIdentity().imaginary, self.EPSILON)) # Perfom another rotate. cmds.rotate(25.0, 50.0, 75.0, objectSpace=True, relative=True) # Re-fetch the USD orientation and check for the update. orientation = orientationsAttr.Get()[instanceIndex] self.assertTrue(Gf.IsClose(orientation.real, 0.397949, self.EPSILON)) self.assertTrue( Gf.IsClose(orientation.imaginary, Gf.Vec3h(-0.0886841, 0.57666, 0.708008), self.EPSILON)) # Now undo, and re-check. cmds.undo() orientation = orientationsAttr.Get()[instanceIndex] self.assertTrue(Gf.IsClose(orientation.real, 0.897461, self.EPSILON)) self.assertTrue( Gf.IsClose(orientation.imaginary, Gf.Vec3h(0.01828, 0.2854, 0.335205), self.EPSILON)) # And once more. # Note that with more complete undo support, this would ideally clear # the authored orientations attribute, returning it to its true # original state. For now, we just validate that the orientation value # is back to its default of identity. cmds.undo() orientation = orientationsAttr.Get()[instanceIndex] self.assertTrue( Gf.IsClose(orientation.real, Gf.Quath.GetIdentity().real, self.EPSILON)) self.assertTrue( Gf.IsClose(orientation.imaginary, Gf.Quath.GetIdentity().imaginary, self.EPSILON))
def _GetSceneItem(instanceIndex=-1): ufePath = testUtilsSelectabilityPointInstanceSelection._GetUfePath( instanceIndex) ufeItem = ufe.Hierarchy.createItem(ufePath) prim = mayaUsdUfe.ufePathToPrim(ufe.PathString.string(ufePath)) return ufeItem, prim