def testAttributeDouble3(self): '''Test the Double3 attribute type.''' # Use our engine method to run the bulk of the test (all the stuff from # the Attribute base class). We use the visibility attribute which is # an Double3 type. ufeAttr, usdAttr = attrDict = self.runTestAttribute( path='/Room_set/Props/Ball_35', attrName='xformOp:translate', ufeAttrClass=ufe.AttributeDouble3, ufeAttrType=ufe.Attribute.kDouble3) # Now we test the Double3 specific methods. # Compare the initial UFE value to that directly from USD. self.assertVectorAlmostEqual(ufeAttr.get(), usdAttr.Get()) # Set the attribute in UFE with some random values. vec = ufe.Vector3d(random.uniform(-100, 100), random.uniform(-100, 100), random.uniform(-100, 100)) ufeAttr.set(vec) # Then make sure that new UFE value matches what it in USD. self.assertVectorAlmostEqual(ufeAttr.get(), usdAttr.Get()) self.runUndoRedo( ufeAttr, ufe.Vector3d(vec.x() - 1.0, vec.y() - 2.0, vec.z() - 3.0))
def testObservation(self): '''Test Attributes observation interface. Test both global attribute observation and per-node attribute observation. ''' # Create three observers, one for global attribute observation, and two # on different UFE items. proxyShapePathSegment = mayaUtils.createUfePathSegment( "|world|transform1|proxyShape1") path = ufe.Path([ proxyShapePathSegment, usdUtils.createUfePathSegment('/Room_set/Props/Ball_34') ]) ball34 = ufe.Hierarchy.createItem(path) path = ufe.Path([ proxyShapePathSegment, usdUtils.createUfePathSegment('/Room_set/Props/Ball_35') ]) ball35 = ufe.Hierarchy.createItem(path) (ball34Obs, ball35Obs, globalObs) = [TestObserver() for i in range(3)] # Maya registers a single global observer on startup. self.assertEqual(ufe.Attributes.nbObservers(), 1) # No item-specific observers. self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) # No notifications yet. self.assertEqual(ball34Obs.notifications, 0) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 0) # Add a global observer. ufe.Attributes.addObserver(globalObs) self.assertEqual(ufe.Attributes.nbObservers(), 2) self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) # Add item-specific observers. ufe.Attributes.addObserver(ball34, ball34Obs) self.assertEqual(ufe.Attributes.nbObservers(), 2) self.assertTrue(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 1) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertTrue(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball35Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) ufe.Attributes.addObserver(ball35, ball35Obs) self.assertTrue(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 1) self.assertEqual(ufe.Attributes.nbObservers(ball35), 1) self.assertTrue(ufe.Attributes.hasObserver(ball35, ball35Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball34Obs)) # Make a change to ball34, global and ball34 observers change. ball34Attrs = ufe.Attributes.attributes(ball34) ball34XlateAttr = ball34Attrs.attribute('xformOp:translate') self.assertEqual(ball34Obs.notifications, 0) ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(1, 2, 3))) self.assertEqual(ball34Obs.notifications, 1) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 1) # Undo, redo cmds.undo() self.assertEqual(ball34Obs.notifications, 2) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 2) cmds.redo() self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 3) # Make a change to ball35, global and ball35 observers change. ball35Attrs = ufe.Attributes.attributes(ball35) ball35XlateAttr = ball35Attrs.attribute('xformOp:translate') ufeCmd.execute(ball35XlateAttr.setCmd(ufe.Vector3d(1, 2, 3))) self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 1) self.assertEqual(globalObs.notifications, 4) # Undo, redo cmds.undo() self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 2) self.assertEqual(globalObs.notifications, 5) cmds.redo() self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 6) # Test removeObserver. ufe.Attributes.removeObserver(ball34, ball34Obs) self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertTrue(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 1) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(4, 5, 6))) self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 7) ufe.Attributes.removeObserver(globalObs) self.assertEqual(ufe.Attributes.nbObservers(), 1) ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(7, 8, 9))) self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 7)
def testObservation(self): ''' Test Attributes observation interface. Test both global attribute observation and per-node attribute observation. ''' # Start we a clean scene so we can get a consistent number of notifications cmds.file(new=True, force=True) mayaUtils.openTopLayerScene() # Create three observers, one for global attribute observation, and two # on different UFE items. proxyShapePathSegment = mayaUtils.createUfePathSegment( "|transform1|proxyShape1") path = ufe.Path([ proxyShapePathSegment, usdUtils.createUfePathSegment('/Room_set/Props/Ball_34') ]) ball34 = ufe.Hierarchy.createItem(path) path = ufe.Path([ proxyShapePathSegment, usdUtils.createUfePathSegment('/Room_set/Props/Ball_35') ]) ball35 = ufe.Hierarchy.createItem(path) (ball34Obs, ball35Obs, globalObs) = [TestObserver() for i in range(3)] # Maya registers a single global observer on startup. self.assertEqual(ufe.Attributes.nbObservers(), 1) # No item-specific observers. self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) # No notifications yet. self.assertEqual(ball34Obs.notifications, 0) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 0) # Add a global observer. ufe.Attributes.addObserver(globalObs) self.assertEqual(ufe.Attributes.nbObservers(), 2) self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) # Add item-specific observers. ufe.Attributes.addObserver(ball34, ball34Obs) self.assertEqual(ufe.Attributes.nbObservers(), 2) self.assertTrue(ufe.Attributes.hasObservers(ball34.path())) self.assertFalse(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 1) self.assertEqual(ufe.Attributes.nbObservers(ball35), 0) self.assertTrue(ufe.Attributes.hasObserver(ball34, ball34Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball35Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball35Obs)) ufe.Attributes.addObserver(ball35, ball35Obs) self.assertTrue(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 1) self.assertEqual(ufe.Attributes.nbObservers(ball35), 1) self.assertTrue(ufe.Attributes.hasObserver(ball35, ball35Obs)) self.assertFalse(ufe.Attributes.hasObserver(ball35, ball34Obs)) # Make a change to ball34, global and ball34 observers change. ball34Attrs = ufe.Attributes.attributes(ball34) ball34XlateAttr = ball34Attrs.attribute('xformOp:translate') self.assertEqual(ball34Obs.notifications, 0) # The first modification adds a new spec to ball_34 & its ancestors # "Props" and "Room_set". Ufe should be filtering out those notifications # so the global observer should still only see one notification. ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(4, 4, 15))) self.assertEqual(ball34Obs.notifications, 1) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 1) # The second modification only sends one USD notification for "xformOps:translate" # because all the spec's already exist. Ufe should also see one notification. ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(4, 4, 20))) self.assertEqual(ball34Obs.notifications, 2) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 2) # Undo, redo cmds.undo() self.assertEqual(ball34Obs.notifications, 3) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 3) cmds.redo() self.assertEqual(ball34Obs.notifications, 4) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 4) # get ready to undo the first modification cmds.undo() self.assertEqual(ball34Obs.notifications, 5) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 5) # Undo-ing the modification which created the USD specs is a little # different in USD, but from Ufe we should just still see one notification. cmds.undo() self.assertEqual(ball34Obs.notifications, 6) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 6) cmds.redo() self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 0) self.assertEqual(globalObs.notifications, 7) # Make a change to ball35, global and ball35 observers change. ball35Attrs = ufe.Attributes.attributes(ball35) ball35XlateAttr = ball35Attrs.attribute('xformOp:translate') # "xformOp:translate" ufeCmd.execute(ball35XlateAttr.setCmd(ufe.Vector3d(4, 8, 15))) self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 1) self.assertEqual(globalObs.notifications, 8) # Undo, redo cmds.undo() self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 2) self.assertEqual(globalObs.notifications, 9) cmds.redo() self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 10) # Test removeObserver. ufe.Attributes.removeObserver(ball34, ball34Obs) self.assertFalse(ufe.Attributes.hasObservers(ball34.path())) self.assertTrue(ufe.Attributes.hasObservers(ball35.path())) self.assertEqual(ufe.Attributes.nbObservers(ball34), 0) self.assertEqual(ufe.Attributes.nbObservers(ball35), 1) self.assertFalse(ufe.Attributes.hasObserver(ball34, ball34Obs)) ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(4, 4, 25))) self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 11) ufe.Attributes.removeObserver(globalObs) self.assertEqual(ufe.Attributes.nbObservers(), 1) ufeCmd.execute(ball34XlateAttr.setCmd(ufe.Vector3d(7, 8, 9))) self.assertEqual(ball34Obs.notifications, 7) self.assertEqual(ball35Obs.notifications, 3) self.assertEqual(globalObs.notifications, 11)